diff --git a/build.gradle b/build.gradle index 51972aa7..ac23bdf2 100644 --- a/build.gradle +++ b/build.gradle @@ -71,6 +71,9 @@ dependencies { testImplementation 'org.junit.jupiter:junit-jupiter:5.10.1' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + + // Add SnakeYaml Docs: https://bitbucket.org/snakeyaml/snakeyaml/wiki/Documentation Installation Info: https://mvnrepository.com/artifact/org.yaml/snakeyaml + implementation group: 'org.yaml', name: 'snakeyaml', version: '1.8' } test { diff --git a/src/main/deploy/robotconfig/example.yml b/src/main/deploy/robotconfig/example.yml new file mode 100644 index 00000000..c4dfb919 --- /dev/null +++ b/src/main/deploy/robotconfig/example.yml @@ -0,0 +1,74 @@ +--- +name: Competition BOT +id: '123' # last year 00802F17DEE0 w + +# Defined subsystems for +subsystems: + drivetrain: + - swerve: true + - tank: false + intake: false + shooter: false + arm: false + +# Below is from last year +drivetrain: + # TRACK_WIDTH: 0.555 + # WH:EEL_RADIUS: 0.0762 + # ENCODER_RESOLUTION: 4096 + # ENCODER_GEAR_RATIO: 1 + # MOTOR_LEFT_MASTER_CAN_ID: 3 + # MOTOR_RIGHT_MASTER_CAN_ID: 4 + # MOTOR_LEFT_FOLLOWER_CAN_ID: 1 + # MOTOR_RIGHT_FOLLOWER_CAN_ID: 2 + # MOTOR_GEAR_RATIO: 8.45 + # BALANCE_P: 0.05 + # BALANCE_I: 0 + # BALANCE_D: 0.03 + # BALANCE_MAX_SPEED: 0.5 + # BALANCE_MIN_DURATION: 1 + # DISTANCE_P: 1 + # DISTANCE_I: 0 + # DISTANCE_D: 0.1 + # DISTANCE_PID_TOLERANCE: 0.1 + # STRAIGHT_P: 0.1 + # STRAIGHT_I: 0 + # STRAIGHT_D: 0 + # ROTATE_P: 0.05 + # ROTATE_I: 0 + # ROTATE_D: 0 + # ROTATE_PID_TOLERANCE: 5 + # DOCK_MAX_SPEED_ON_GROUND: 1.5 + # DOCK_MAX_SPEED_ON_RAMP: 0.5 + # DOCK_ON_RAMP_DURATION_MIN: 0.2 + # DOCK_LEVELING_OFF_DURATION_MIN: 0.2 + # DOCK_RAMP_ROLL_MIN 10 + # DOCK_RAMP_ROLL_MAX: 15 + # DOCK_LEVELING_ROLL_MIN: 6 + +sysid: + # MAX_SPEED: 3 + # MAX_ANGULAR_SPEED: 4 + # COMBINED_FEED_BACK_VELOCITY_P: 3.9725 + # COMBINED_FEED_BACK_VELOCITY_I: 0 + # COMBINED_FEED_BACK_VELOCITY_D: 0 + # LEFT_FEED_BACK_VELOCITY_P: 3.7381 + # LEFT_FEED_BACK_VELOCITY_I: 0 + # LEFT_FEED_BACK_VELOCITY_D: 0 + # RIGHT_FEED_BACK_VELOCITY_P: 3.7865 + # RIGHT_FEED_BACK_VELOCITY_I: 0 + # RIGHT_FEED_BACK_VELOCITY_D: 0 + + # FEED_FORWARD_LINEAR_S: 1.0842 + # FEED_FORWARD_LINEAR_V: 2.3958 + # FEED_FORWARD_LINEAR_A: 1.195 + # LEFT_FEED_FORWARD_LINEAR_S: 1.0421 + # LEFT_FEED_FORWARD_LINEAR_V: 2.3821 + # LEFT_FEED_FORWARD_LINEAR_A: 0.56617 + # RIGHT_FEED_FORWARD_LINEAR_S: 1.0946 + # RIGHT_FEED_FORWARD_LINEAR_V: 2.404 + # RIGHT_FEED_FORWARD_LINEAR_A: 0.6552 + + # FEED_FORWARD_ANGULAR_S: 1.0005 + # FEED_FORWARD_ANGULAR_V: 3.0117 + # FEED_FORWARD_ANGULAR_A: 2.9661 diff --git a/src/main/java/frc/robot/Robot.java b/src/main/java/frc/robot/Robot.java index 01bfba15..1d1ac5ff 100644 --- a/src/main/java/frc/robot/Robot.java +++ b/src/main/java/frc/robot/Robot.java @@ -6,6 +6,7 @@ import edu.wpi.first.wpilibj2.command.Command; import edu.wpi.first.wpilibj2.command.CommandScheduler; +import frc.robot.utils.RobotConfig; // START: Setup AdvantageKit import org.littletonrobotics.junction.LoggedRobot; import org.littletonrobotics.junction.Logger; @@ -20,6 +21,9 @@ public class Robot extends LoggedRobot { @Override public void robotInit() { + + RobotConfig.loadConfig(); + // START: Setup AdvantageKit // Record build metadata generated by gversion diff --git a/src/main/java/frc/robot/utils/RobotConfig.java b/src/main/java/frc/robot/utils/RobotConfig.java new file mode 100644 index 00000000..6b8f24bb --- /dev/null +++ b/src/main/java/frc/robot/utils/RobotConfig.java @@ -0,0 +1,82 @@ +package frc.robot.utils; + +import edu.wpi.first.wpilibj.Filesystem; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import java.util.Map; +import org.yaml.snakeyaml.Yaml; + +public class RobotConfig { + public static Map loadConfig() { + try { + String robotConfigPath = getRobotConfigFilePath(); + + // Create an InputStream to read the YAML file + try { + InputStream input = new FileInputStream(robotConfigPath); + Yaml yaml = new Yaml(); + + // Parse the YAML file into a Map + Map configData = (Map) yaml.load(input); + + // Access values from the Map + String robotName = (String) configData.get("name"); + String robotId = (String) configData.get("id"); + + // Print the loaded robot config information + System.out.println("Loaded robot config: " + robotConfigPath); + System.out.println("Robot Name: " + robotName + " Id: " + robotId); + + // Access subsystems if they exist This is more of a test to see if it loaded correctly + if (configData.containsKey("subsystems")) { + System.out.println("Subsystems: " + configData.get("subsystems")); + } + + return configData; + } catch (Exception e) { + } + } catch (Exception e) { + e.printStackTrace(); + System.out.println("Failed to load robot config. Robot will not function"); + } + return null; + } + + // get the config file path + private static String getRobotConfigFilePath() throws Exception { + + String robotConfigFilePathPrefix = "robotconfig"; + String robotUniqueId = getMacAddress(); + String robotConfigFilePathSuffix = ".yml"; + + String filePath = + Filesystem.getDeployDirectory() // deploy folder + + File.separator + + robotConfigFilePathPrefix + + File.separator + + robotUniqueId + + robotConfigFilePathSuffix; + + if (fileExists(filePath)) { + return filePath; + } else { + System.out.println("Can't find a valid robot config YAML file in: " + filePath); + throw new Exception("Can't find a valid robot config YAML file in: " + filePath); + } + } + + // Placeholder macAddress, replace with new + private static String getMacAddress() { + return "example"; + } + + // Checks if the fill exist + private static boolean fileExists(String filePathString) { + File f = new File(filePathString); + if (f.isFile()) { + return true; + } + return false; + } +}