Because configuration objects are not tied to a single device, they can be used multiples times for multiple devices of the same type, reducing the amount of boilerplate code for devices that function similarly.
Configuration classes provide an apply()
method to apply parameters from one configuration to another, providing greater flexibility when configuring multiple devices of the same type.
For example, you can create a common configuration for multiple devices of the same type and apply it to each device's individual configuration. This simplifies setup by avoiding duplicated code, allowing you to focus on setting only the unique parameters for each device.
Depending on the configuration class, multiple overloaded apply()
methods may be provided. However, the simplest form of apply()
accepts a configuration object of the same type as the target. Just like the other parameter setting methods, apply()
returns a modified instance of the object for method chaining.
Importantly, applying a configuration is distinct from copying it. Copying would completely overwrite the target configuration, including potentially removing parameters previously set. Instead, apply()
selectively updates parameters.
The apply()
method updates only the parameters that exist in the passed configuration object. Parameters in the target configuration that are not present in the passed configuration remain unchanged. If a parameter exists in both the target and the passed configurations, the value from the passed configuration takes precedence.
Below is a basic example of how apply()
can be used to create a starting point from another configuration:
You can also adjust parameters that were set from calling apply()
:
Calling apply()
may override previously set parameters, so it is important to keep ordering in consideration:
For configuration classes that contain sub-configurations, using the base apply()
will also apply the parameters from the passed object's sub-configurations to the target's. The same will apply to further nested sub-configurations.
Configuration classes that contain sub-configurations will also provide overloaded methods of apply()
for each of its sub-configurations. These methods allow you to apply a sub-configuration object to multiple parent configurations.
Similar to configuration classes, devices will have a corresponding configuration accessor class. These accessor classes will contain methods to get parameters directly from the device. The structure of the accessor class resemble that of the respective configuration class where sub-configurations have corresponding nested accessors.
However, there is no need to manually instantiate a configuration accessor, as it is automatically handled by the device class. The device class has a public member object of its accessor class called configAccessor
which can be used to get configuration parameters.
Below is an example of how to get a configuration parameter from a device:
Here is how to get a nested configuration parameter:
This only applies to Java and C++.
Starting 2025, REVLib shifted its device configuration paradigm towards something more declarative. This approach promotes better code organization and readability while also reducing boilerplate code. Additionally, it opens the door for enhanced configuration validation as well as reusability of code, aligning with principles of good object-oriented design.
This page explores how different parts of REVLib's configuration paradigm works and how you can use it effectively in your robot program. For more information on device specific configurations, see the following:
Color Sensor V3 does not follow the device configuration paradigm described on this page.
In this configuration paradigm, each device has its own dedicated configuration class which serves as a structure for organizing and storing the parameters to be configured for that device.
All parameters in a configuration are optional, meaning all parameters will remain unchanged unless otherwise specified. This minimizes the traffic between REVLib and the device when applying the configuration.
As a result, configuration classes are not intended to represent the device's complete configuration—though this is possible, it is generally unnecessary. Their primary purpose is to set only the parameters that are relevant to your needs.
For details on retrieving parameters from a device, refer to this section.
Configuration parameters can be set via methods on a config object, and those methods return a modified instance of the object, allowing you to perform method chaining for more organized and readable code.
Below is an example of how you would set parameters using method chaining:
Config classes can also contain sub-configs as members of the class, allowing for improved organization by grouping conceptually-related configuration parameters together. Since a sub-config is its own configuration class, its methods return the sub-config instead of its parent. To configure something outside the sub-config, you'll need to start a new chain of method calls.
Additionally, a sub-config can have its own sub-configs, allowing parameters to be deeply nested within the hierarchy.
Applying the concepts described above, this is how an example configuration class would be composed.
After setting up your configuration object, you can apply the configuration by calling the configure()
method on your device object.
The method signature may differ between devices, so be sure to consult the device's configuration documentation. In all cases, however, configure()
takes a configuration object and a ResetMode
value as arguments and returns a REVLibError
.
The ResetMode
argument specifies whether to reset the parameters before applying the configuration. This argument is required to ensure the user makes the conscious decision whether to reset the parameters, helping to avoid potential pitfalls.
Resetting parameters before applying a new configuration ensures the device starts in a known, good state. This is particularly useful when initializing the device at the start of a program, and by starting with a clean slate, you can guarantee the configuration is consistent each time the robot powers up. This approach is especially valuable when performing a drop-in replacement for a device, as the replacement may be in an unknown state.
A reason to not reset parameters when applying a configuration is to preserve previously set values during a mid-operation adjustment. While reconfiguring a device during operation is generally discouraged, some use cases may necessitate it.
Another reason to not reset parameters is when you are using the REV Hardware Client as your primary configuration tool. Although configuring devices through code is considered a best practice, the Hardware Client remains a valid and supported option for configuration.
Below is an example of either case: