send sends commands and settings to modules.
This method provides a variety of selectors to send commands, gains,
LEDs, as well as a several useful settings and flags. This method returns
immediately and does not wait until outgoing packets have arrived at
the receiving modules.
'Boot' boots a module from bootloader mode into application
mode. It expects a boolean value (true will boot) and can
only be used in supported modes (e.g. bootloader mode).
'Command' ('cmd') is used to send common control loop set points
such as positions, velocities, or efforts. It expects a CommandStruct.
If struct fields are empty or filled with NaN, the underlying control
is disabled. For the common use case (set CommandStruct), the flag can
be omitted (both valid use cases are shown below).
Example
% Enable/disable velocity control
cmd = CommandStruct();
cmd.velocity = zeros(1, group.getNumModules);
t0 = tic;
while toc(t0) < 5
fbk = group.getNextFeedback: % limit loop rate
group.send('cmd', cmd);
end
cmd.velocity = [];
group.send(cmd);
'IoCommand' ('IoCmd') is used to send pin commands to supporting
modules, e.g., I/O boards. It expects an IoCommandStruct. Fields that
are empty or contain NaN/Inf values will not be sent. For the common
use case (set IoCommandStruct), the flag can be omitted.
Example
% map pins (improves readability)
selectedPin = 'e1';
% set digital pin to 1
ioCmd = IoCommandStruct();
ioCmd.(selectedPin) = 1;
group.send(ioCmd);
'Gains' sets control loop gains. Note that there are many tuning
parameters that depend on the used control strategy. If you need
to reset gains, you can simply reboot a module to restore the
previously persisted gains.
Example
% set effort limits of +/- 1.5 Nm
n = group.getNumModules();
limit = 1.5;
gains = GainStruct();
gains.effortMaxOutput = ones(1,n) * limit;
gains.effortMinOutput = ones(1,n) * -limit;
group.send('gains', gains);
'SafetyParams' sets safety related parameters such as joint
limits. If you need to reset parameters, you can simply
reboot the device to restore previously persisted
parameters.
Example
% remove position limits
limits = SafetyParamsStruct();
limits.positionMinLimit = ones(1,n) * -inf;
limits.positionMaxLimit = ones(1,n) * +inf;
group.send('SafetyParams', limits);
'LED' sets the led color. This is often useful when synchronizing video
to feedback and for timing analysis in combination with a high-speed
camera. Colors can be set identically for all modules, or individually
for each module. The string mappings can be found in 'help plot'.
Example
group.send('led', 'red'); % set all to red
group.send('led', [0 0 1]); % set all to blue [r g b] [0-1]
group.send('led', []); % reset to default mode
'Name' sets the names for individual modules. It expects a {1xN cell}
array of module names, where N is the number of modules in a group.
Valid names are limited to alphanumerical characters, spaces, and
underscores.
'Family' sets the family for all or individual modules. It expects a
single string or an {1xN cell} array of strings. Valid families are
limited to alphanumerical characters, spaces, and underscores.
'Persist' saves all the settings and gains that are currently set on
on a module, so that they are loaded after reboot. It expects a
boolean value. True will save settings, false has no effect.
'Reset' reboots a module. It expects a boolean value and can only be
used in supported modes (e.g. application mode). True will reboot a
module, false has no effect.
'PositionLimit' ('PosLim') sets safety limits for position.
Safety limits act as a virtual hard stop and are independent of gains.
'VelocityLimit' ('VelLim') sets safety limits for velocity.
Safety limits act as a virtual hard stop and are independent of gains.
'EffortLimit' ('EffLim') sets safety limits for effort.
Safety limits act as a virtual hard stop and are independent of gains.
'ReferencePosition' sets the current position (feedback) by adjusting
the user-settable reference point for the zero position. This persists
automatically. This is the same as setting the reference point for
Position in the 'Device' tab of the Scope GUI.
'OffsetReferencePosition' offsets the current position (feedback) by
offsetting the user-settable reference point for the zero position.
'ZeroReferenceDeflection' sets the deflection of the internal spring
to zero. Note that this will also cause the effort (feedback) to also be
zero. Only do this when the actuator is unloaded.
'OffsetReferenceDeflection' adjusts the internal spring deflection. Note
that this will cause a jump in the effort feedback that depends on the
spring constant (may or may not be linear).
'SpringConstant' sets the internal stiffness parameter for an actuator
that is used to turn its sensed spring deflection into an estimated
effort (torque). This is a linear spring constant, units are Nm/rad.
The current spring constant can be determined by getting a 'full'
feedback and dividing the negative effort by the measured deflection
(-fbk.effort ./ fbk.deflection).
'RequestAck' ('Ack') requests message acknowledgements from each
device. This method will return true if acknowledgements have been
received from all devices within this group and within the specified
timeout.
'Timeout' [s] the deadline for receiving acknowledgements before
this method aborts and returns false. (Default 0.5s)
'AccelIncludeGravity' [true|false] allows removing accelerations
due to gravity from the accelerometer feedback at the device level.
This has no effect on devices without hardware support.
'AppendLog' [string] appends a string to devices that support log
output. This is often useful for providing user feedback on mobile
applications.
'ClearLog' [true] clears log output generated by 'AppendLog'.
Example
% Provide continuous user feedback to a mobile controller
group = HebiLookup.newGroupFromNames('HEBI','mobileIO');
while true
fbk = group.getNextFeedbackIO();
logMsg = ['A1: ' num2str(fbk.a1) newline ...
'A2: ' num2str(fbk.a2) newline ...
'B1: ' num2str(fbk.b1) newline];
group.send('ClearLog', true, 'AppendLog', logMsg);
end
Note that all options can be combined as required. Options that get set
in the same function call will be packed into the same outgoing packet.
Example
% Indicate with led that family has been set
group.send('family', 'MyRobot', 'led', 'r');