Files
YAGSL/swervelib/parser/SwerveParser.java

205 lines
7.8 KiB
Java
Raw Permalink Normal View History

2023-02-13 17:21:24 -06:00
package swervelib.parser;
2023-02-13 14:37:05 -06:00
2025-02-22 06:15:56 +00:00
import com.fasterxml.jackson.databind.DeserializationFeature;
2023-02-13 14:37:05 -06:00
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
2024-12-09 23:26:04 +00:00
import edu.wpi.first.math.geometry.Pose2d;
2023-02-13 14:37:05 -06:00
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
2023-02-13 17:21:24 -06:00
import swervelib.SwerveDrive;
import swervelib.SwerveModule;
2023-11-09 17:32:48 -06:00
import swervelib.math.SwerveMath;
2023-02-13 17:21:24 -06:00
import swervelib.parser.json.ControllerPropertiesJson;
import swervelib.parser.json.ModuleJson;
import swervelib.parser.json.PIDFPropertiesJson;
import swervelib.parser.json.PhysicalPropertiesJson;
import swervelib.parser.json.SwerveDriveJson;
2023-02-13 14:37:05 -06:00
/**
* Helper class used to parse the JSON directory with specified configuration options.
*/
public class SwerveParser
{
/**
* Module number mapped to the JSON name.
*/
2023-02-13 14:37:05 -06:00
private static final HashMap<String, Integer> moduleConfigs = new HashMap<>();
/**
* Parsed swervedrive.json
*/
public static SwerveDriveJson swerveDriveJson;
/**
* Parsed controllerproperties.json
*/
public static ControllerPropertiesJson controllerPropertiesJson;
/**
* Parsed modules/pidfproperties.json
*/
public static PIDFPropertiesJson pidfPropertiesJson;
/**
* Parsed modules/physicalproperties.json
*/
public static PhysicalPropertiesJson physicalPropertiesJson;
/**
* Array holding the module jsons given in {@link SwerveDriveJson}.
*/
public static ModuleJson[] moduleJsons;
/**
* Construct a swerve parser. Will throw an error if there is a missing file.
*
* @param directory Directory with swerve configurations.
* @throws IOException if a file doesn't exist.
2023-02-13 14:37:05 -06:00
*/
public SwerveParser(File directory) throws IOException
{
checkDirectory(directory);
swerveDriveJson =
new ObjectMapper()
2025-02-22 06:15:56 +00:00
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.readValue(new File(directory, "swervedrive.json"), SwerveDriveJson.class);
controllerPropertiesJson =
new ObjectMapper()
2025-02-22 06:15:56 +00:00
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.readValue(
new File(directory, "controllerproperties.json"), ControllerPropertiesJson.class);
pidfPropertiesJson =
new ObjectMapper()
2025-02-22 06:15:56 +00:00
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.readValue(
new File(directory, "modules/pidfproperties.json"), PIDFPropertiesJson.class);
physicalPropertiesJson =
new ObjectMapper()
2025-02-22 06:15:56 +00:00
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.readValue(
new File(directory, "modules/physicalproperties.json"),
PhysicalPropertiesJson.class);
2023-02-13 14:37:05 -06:00
moduleJsons = new ModuleJson[swerveDriveJson.modules.length];
for (int i = 0; i < moduleJsons.length; i++)
{
moduleConfigs.put(swerveDriveJson.modules[i], i);
File moduleFile = new File(directory, "modules/" + swerveDriveJson.modules[i]);
assert moduleFile.exists();
2025-02-22 06:15:56 +00:00
moduleJsons[i] = new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.readValue(moduleFile, ModuleJson.class);
2023-02-13 14:37:05 -06:00
}
}
/**
* Get the swerve module by the json name.
*
* @param name JSON name.
* @param driveConfiguration {@link SwerveDriveConfiguration} to pull from.
* @return {@link SwerveModuleConfiguration} based on the file.
*/
public static SwerveModule getModuleConfigurationByName(
String name, SwerveDriveConfiguration driveConfiguration)
2023-02-13 14:37:05 -06:00
{
return driveConfiguration.modules[moduleConfigs.get(name + ".json")];
}
/**
* Open JSON file.
*
* @param file JSON File to open.
* @return JsonNode of file.
*/
private JsonNode openJson(File file)
{
try
{
return new ObjectMapper().readTree(file);
} catch (IOException e)
{
throw new RuntimeException(e);
}
}
/**
* Check directory structure.
*
* @param directory JSON Configuration Directory
*/
private void checkDirectory(File directory)
{
assert new File(directory, "swervedrive.json").exists();
assert new File(directory, "controllerproperties.json").exists();
assert new File(directory, "modules").exists() && new File(directory, "modules").isDirectory();
assert new File(directory, "modules/pidfproperties.json").exists();
assert new File(directory, "modules/physicalproperties.json").exists();
}
/**
* Create {@link SwerveDrive} from JSON configuration directory.
*
2023-11-09 17:32:48 -06:00
* @param maxSpeed Maximum speed of the robot in meters per second, used for both angular acceleration used in
* {@link swervelib.SwerveController} and drive feedforward in
* {@link SwerveMath#createDriveFeedforward(double, double, double)}.
2023-02-13 14:37:05 -06:00
* @return {@link SwerveDrive} instance.
*/
2023-11-09 17:32:48 -06:00
public SwerveDrive createSwerveDrive(double maxSpeed)
{
2024-12-09 23:26:04 +00:00
return createSwerveDrive(maxSpeed, Pose2d.kZero);
2023-11-09 17:32:48 -06:00
}
/**
* Create {@link SwerveDrive} from JSON configuration directory.
*
* @param maxSpeed Maximum speed of the robot in meters per second, used for both angular
* acceleration used in {@link swervelib.SwerveController} and drive feedforward in
* {@link SwerveMath#createDriveFeedforward(double, double, double)}.
* @param angleMotorConversionFactor Angle (AKA azimuth) motor conversion factor to convert motor controller PID loop
* units to degrees, usually created using
* {@link SwerveMath#calculateDegreesPerSteeringRotation(double, double)}.
* @param driveMotorConversion Drive motor conversion factor to convert motor controller PID loop units to
* meters per rotation, usually created using
* {@link SwerveMath#calculateMetersPerRotation(double, double, double)}.
* @return {@link SwerveDrive} instance.
*/
public SwerveDrive createSwerveDrive(double maxSpeed, double angleMotorConversionFactor, double driveMotorConversion)
{
2024-12-09 23:26:04 +00:00
physicalPropertiesJson.conversionFactors.angle.factor = angleMotorConversionFactor;
physicalPropertiesJson.conversionFactors.drive.factor = driveMotorConversion;
return createSwerveDrive(maxSpeed, Pose2d.kZero);
2023-11-09 17:32:48 -06:00
}
/**
* Create {@link SwerveDrive} from JSON configuration directory.
*
2024-12-09 23:26:04 +00:00
* @param maxSpeed Maximum speed of the robot in meters per second for normal+angular acceleration in
* {@link swervelib.SwerveController} of the robot
* @param initialPose {@link Pose2d} initial pose.
2023-11-09 17:32:48 -06:00
* @return {@link SwerveDrive} instance.
*/
2024-12-09 23:26:04 +00:00
public SwerveDrive createSwerveDrive(double maxSpeed, Pose2d initialPose)
2023-02-13 14:37:05 -06:00
{
SwerveModuleConfiguration[] moduleConfigurations =
new SwerveModuleConfiguration[moduleJsons.length];
2023-02-13 14:37:05 -06:00
for (int i = 0; i < moduleConfigurations.length; i++)
{
ModuleJson module = moduleJsons[i];
moduleConfigurations[i] =
module.createModuleConfiguration(
pidfPropertiesJson.angle,
pidfPropertiesJson.drive,
2023-11-09 17:32:48 -06:00
physicalPropertiesJson.createPhysicalProperties(),
2023-04-08 12:31:07 -05:00
swerveDriveJson.modules[i]);
2023-02-13 14:37:05 -06:00
}
SwerveDriveConfiguration swerveDriveConfiguration =
new SwerveDriveConfiguration(
moduleConfigurations,
swerveDriveJson.imu.createIMU(),
2023-11-09 17:32:48 -06:00
swerveDriveJson.invertedIMU,
physicalPropertiesJson.createPhysicalProperties());
2023-02-13 14:37:05 -06:00
return new SwerveDrive(
swerveDriveConfiguration,
2024-12-09 23:26:04 +00:00
controllerPropertiesJson.createControllerConfiguration(swerveDriveConfiguration, maxSpeed),
maxSpeed,
initialPose);
2023-02-13 14:37:05 -06:00
}
}