Canandmag Settings¶
The CanandmagSettings object is used to reconfigure the Canandmag.
Creation¶
// Create with no values
// Only values that are changed will be updated on the device
Canandmag.Settings settings = new Canandmag.Settings();
// Make a copy of an existing CanandmagSettings object.
Canandmag.Settings copiedSettings = new Canandmag.Settings(settings);
// Create with no values
// Only values that are changed will be updated on the device
Canandmag.Settings settings{}
// Make a copy of an existing CanandmagSettings object.
Canandmag.Settings copiedSettings{settings};
Values are fetched and updated using the getters and setters of the object.
Important
Only values updated by the user are changed on the device. Values that are not changed will remain untouched.
Writing Settings To The Canandmag¶
When you are ready to send and save the settings to the device, you can use Canandmag.setSettings
to transmit the contents of a CanandmagSettings object to the Canandmag.
// A canandmag object with CAN ID 0
Canandmag canandmag = new Canandmag(0);
// Create a new settings object and add a value to set
CanandmagSettings settings = new CanandmagSettings();
// disable the zero button
settings.setDisableZeroButton(true);
// Write the settings to the Canandcolor with a timeout of 50 milliseconds per setting.
// By default the settings will be written to flash -- they will persist on reboots.
// If this is not desired, one can use
//
// settings.setEphemeral(true);
//
// to flag the settings as ephemeral (and not persist in flash on reboot).
canandmag.setSettings(settings, 0.050);
// A canandmag object with CAN ID 0
Canandmag canandmag{0};
// Create a new settings object and add a value to set
CanandmagSettings settings{};
// disable the zero button
settings.SetDisableZeroButton(true);
// Write the settings to the Canandcolor with a timeout of 50 milliseconds per setting.
// By default the settings will be written to flash -- they will persist on reboots.
// If this is not desired, one can use
//
// settings.setEphemeral(true);
//
// to flag the settings as ephemeral (and not persist in flash on reboot).
canandmag.SetSettings(settings, 0.050_s);
Fetching Settings From Device¶
Settings can be fetched from the end device in both a synchronous and asychronous manner. Due to the synchronous method blocking for 0.15-0.25 seconds, it is recommended to use it only in initialization routines for an autonomous or teleop program.
getSettings will return null if the fetch times out before the device responds.
The method allSettingsReceived in the CanandmagSettings object can be used to determine if all settings have been fetched when working with async settings fetch.
In addition, if getSettingsAsync is called after updating a Canandmag’s settings, it will be populated with the fields that have been echoed by the device in its settings confirmation messages. For example, if the status frame is changed from 1 second to 2 seconds, repeated calls to getSettingsAsync will first returns either -1 in Java or nullopt in c++ for the status frame time, until confirmation that the status frame time has been updated, at which point the field will change to 2 seconds (the value set before).
Synchronous (blocking)
// A Canandmag object with CAN ID 0
Canandmag canandmag = new Canandmag(0);
// Fetch this Canandmag's settings.
// This runs with a default timeout of 0.35 seconds.
Canandmag.Settings settings = canandmag.getSettings();
// Fetch this Canandmag's settings.
// This runs with a timeout of 0.5 seconds
Canandmag.Settings settings = canandmag.getSettings(0.5);
// Fetch the status frame period from the received settings
// This will be either a double (seconds) or null if the status frame period
// was not successully received.
if (settings.getStatusFramePeriod() != null) {
System.out.printf("Status frame period: %d\n", settings.getStatusFramePeriod());
} else {
System.out.println("getStatusFramePeriod returned null :/");
}
using namespace redux::sensors::canandcolor;
// A Canandmag object with CAN ID 0
Canandmag canandmag{0};
// Fetch this Canandmag's settings
// This runs with a default timeout of 0.35 seconds
CanandmagSettings = canandmag.GetSettings();
// Fetch this canandmag's settings
// This runs with a timeout of 0.5 seconds
CanandmagSettings = canandmag.GetSettings(0.5_s);
// Fetch the status frame period from the received settings
// This will be either a double (seconds) or null if the status frame period
// was not successully received.
if (settings.GetStatusFramePeriod()) {
fmt::print("Status frame period: {}\n", settings.GetStatusFramePeriod());
} else {
fmt::print("GetStatusFramePeriod returned std::nullopt :/");
}
Asynchronous (non-blocking)
// A Canandmag object with CAN ID 0
Canandmag canandmag = new Canandmag(0);
// Start the settings fetch
canandmag.startFetchSettings();
// ...spend some period of time waiting for settings...
Canandmag.Settings settings = canandmag.getSettingsAsync();
if (settings.allSettingsReceived()) {
// We now know all settings have been received
// ...do things with the settings object here...
}
using namespace redux::sensors::canandmag;
// A Canandmag object with CAN ID 0
Canandmag canandmag{0};
// Start the settings fetch
canandmag.StartFetchSettings();
//...spend some period of time waiting for settings...
CanandmagSettings settings = canandmag.GetSettingsAsync();
if (settings.AllSettingsReceived()) {
// We now know all settings have been received
// ...do things with the settings object here...
}
Velocity Filter¶
The width of the onboard velocity filter in milliseconds is configurable. The onboard velocity filter works by averaging the change in encoder value over a set period of time. While lower values of the filter width will be more responsive (update faster), it will also be more noisy. Higher values of the filter width will be more stable, at the cost of some responsiveness. The minimum width is 0.25 milliseconds, and the maximum value is 63.75 milliseconds. The value is set to a precision of 0.25 milliseconds.
Default value: 25 milliseconds
Minimum value: 0.25 milliseconds
Maximum value: 63.75 milliseconds
// Sets the velocity filter width to 25 milliseconds
settings.setVelocityFilterWidth(25);
// Sets the velocity filter width to 25 milliseconds
settings.setVelocityFilterWidth(25_ms);
Position Frame Period¶
The position frame period is the time between position pockets being sent by the Helium Canandmag over the CAN Bus. By default, this value is 0.020 seconds, meaning a position packet is sent every 20 milliseconds (for a total of 50 times a second). Lower values will mean packets get sent more frequently, but will correspondingly increase CAN bus utilization. This value can be set to 0, which disables the position output. The maximum value of this value is 65.535 seconds (65535 milliseconds). This value is set with a resolution of 0.001 seconds (1 millisecond).
Default value: 0.020 seconds
Minimum value: 0 seconds (disables position output)
Maximum value: 65.535 seconds
FIRST® Robotics Competition
The CAN 2.0B bus in the FIRST® Robotics Competition operates at a rate of 1 Mbit/s, or 125000 bytes per second. To estimate CAN usage, you can multiply the size of the CAN packet by its send frequency in hertz, and divide that by 125000. CAN packets have 8 bytes of overhead. For example, a position packet is 6 bytes of data, so the full packet is 14 bytes. At 0.020 seconds, or 50 times a second, this takes up 700 / 125000 or 0.56% of the CAN bus.
// Sets the position frame period to 20 milliseconds
settings.setPositionFramePeriod(0.020);
// Sets the position frame period to 20 milliseconds
settings.SetPositionFramePeriod(20_ms);
Velocity Frame Period¶
The velocity frame period is the time between velocity pockets being sent by the Helium Canandmag over the CAN Bus. By default, this value is 0.020 seconds, meaning a velocity packet is sent every 20 milliseconds (for a total of 50 times a second). Lower values will mean packets get sent more frequently, but will correspondingly increase CAN bus utilization. This value can be set to 0, which disables the velocity output. The maximum value of this value is 65.535 seconds (65535 milliseconds). This value is set with a resolution of 0.001 seconds (1 millisecond).
Default value: 0.020 seconds
Minimum value: 0 seconds (disables velocity output)
Maximum value: 65.535 seconds
// Sets the velocity frame period to 20 milliseconds
settings.setVelocityFramePeriod(0.020);
// Sets the velocity frame period to 20 milliseconds
settings.SetVelocityFramePeriod(20_ms);
Status Frame Period¶
The status frame period is the time between status pockets being sent by the Helium Canandmag over the CAN Bus. By default, this value is 1 second, meaning a status packet is sent every 1000 milliseconds. Lower values will mean packets get sent more frequently, but will correspondingly increase CAN bus utilization. This value cannot be set to zero or disabled. The maximum value of this value is 16.383 seconds (16383 milliseconds). This value is set with a resolution of 0.001 seconds (1 millisecond).
Default value: 1 second
Minimum value: 0.001 seconds
Maximum value: 16.383 seconds
Note
So what does the status frame actually do? The status frame carries information about the active faults (problems) with the device, its internal temperature reading, and some other general status information. This packet cannot be disabled as it is used for diagnostics and other critical functions.
// Sets the status frame period to 1 second
settings.setStatusFramePeriod(1);
// Sets the status frame period to 1 second
settings.SetStatusFramePeriod(1_s);
Invert Direction¶
Setting the invert direction flag will invert the direction that the encoder reads.
By default the encoder reads positive as: * counterclockwise with the point of view opposite the sensor face * clockwise facing top-down from most swerve modules * clounterclockwise with the point of view towards the through-bore’s sensor casing.
Setting this to true will flip the direction of rotation read as positive (e.g. clockwise instead of counterclockwise.)
Default value: false
// Sets the inversion to false
settings.setInvertDirection(false);
// Sets the inversion to false
settings.SetInvertDirection(false);