diff --git a/shared/examplecheck.gradle b/shared/examplecheck.gradle new file mode 100644 index 0000000000..64a83c75c6 --- /dev/null +++ b/shared/examplecheck.gradle @@ -0,0 +1,47 @@ +def fileCheck = { file, folder -> + def folderNames = new groovy.json.JsonSlurper().parseText(file.text).collect { it.foldername } + def folders = [] + folder.eachDir { + folders << it.name + } + def disjunct = (folders + folderNames) - folders.intersect(folderNames) + def missingFromFolders = folderNames.intersect(disjunct) + def missingFromJson = folders.intersect(disjunct) + + if (!missingFromFolders.empty || !missingFromJson.empty) { + StringBuilder missingString = new StringBuilder(); + missingString.append("Missing From Folders\n") + for (String symbol : missingFromFolders) { + missingString.append(symbol); + missingString.append('\n'); + } + missingString.append("\nMissing from JSON\n") + for (String symbol : missingFromJson) { + missingString.append(symbol); + missingString.append('\n'); + } + throw new GradleException("Found missing items\n" + missingString.toString()); + } +} + +task checkTemplates(type: Task) { + doLast { + fileCheck(templateFile, templateDirectory) + } +} + +task checkExamples(type: Task) { + doLast { + fileCheck(exampleFile, exampleDirectory) + } +} + +task checkCommands(type: Task) { + doLast { + fileCheck(commandFile, commandDirectory) + } +} + +check.dependsOn checkTemplates +check.dependsOn checkExamples +check.dependsOn checkCommands diff --git a/wpilibcExamples/build.gradle b/wpilibcExamples/build.gradle index 421f3aa46b..a0636c776d 100644 --- a/wpilibcExamples/build.gradle +++ b/wpilibcExamples/build.gradle @@ -193,3 +193,14 @@ model { } } apply from: 'publish.gradle' + +ext { + templateDirectory = new File("$projectDir/src/main/cpp/templates/") + templateFile = new File("$projectDir/src/main/cpp/templates/templates.json") + exampleDirectory = new File("$projectDir/src/main/cpp/examples/") + exampleFile = new File("$projectDir/src/main/cpp/examples/examples.json") + commandDirectory = new File("$projectDir/src/main/cpp/commands/") + commandFile = new File("$projectDir/src/main/cpp/commands/commands.json") +} + +apply from: "${rootDir}/shared/examplecheck.gradle" diff --git a/wpilibcExamples/src/main/cpp/examples/MotorControlEncoder/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/MotorControlEncoder/cpp/Robot.cpp new file mode 100644 index 0000000000..97a3f52d91 --- /dev/null +++ b/wpilibcExamples/src/main/cpp/examples/MotorControlEncoder/cpp/Robot.cpp @@ -0,0 +1,51 @@ +/*----------------------------------------------------------------------------*/ +/* Copyright (c) 2017-2018 FIRST. All Rights Reserved. */ +/* Open Source Software - may be modified and shared by FRC teams. The code */ +/* must be accompanied by the FIRST BSD license file in the root directory of */ +/* the project. */ +/*----------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include + +constexpr double kPi = 3.14159265358979; + +/** + * This sample program shows how to control a motor using a joystick. In the + * operator control part of the program, the joystick is read and the value is + * written to the motor. + * + * Joystick analog values range from -1 to 1 and speed controller inputs as + * range from -1 to 1 making it easy to work together. + * + * In addition, the encoder value of an encoder connected to ports 0 and 1 is + * consistently sent to the Dashboard. + */ +class Robot : public frc::IterativeRobot { + public: + void TeleopPeriodic() override { m_motor.Set(m_stick.GetY()); } + + /* + * The RobotPeriodic function is called every control packet no matter the + * robot mode. + */ + void RobotPeriodic() override { + frc::SmartDashboard::PutNumber("Encoder", m_encoder.GetDistance()); + } + + void RobotInit() override { + // Use SetDistancePerPulse to set the multiplier for GetDistance + // This is set up assuming a 6 inch wheel with a 360 CPR encoder. + m_encoder.SetDistancePerPulse((kPi * 6) / 360.0); + } + + private: + frc::Joystick m_stick{0}; + frc::Spark m_motor{0}; + frc::Encoder m_encoder{0, 1}; +}; + +int main() { return frc::StartRobot(); } diff --git a/wpilibcExamples/src/main/cpp/examples/examples.json b/wpilibcExamples/src/main/cpp/examples/examples.json index d1560639c5..44ebb16cb0 100644 --- a/wpilibcExamples/src/main/cpp/examples/examples.json +++ b/wpilibcExamples/src/main/cpp/examples/examples.json @@ -7,7 +7,9 @@ "Actuators", "Joystick", "Complete List" - ] + ], + "foldername": "MotorControl", + "gradlebase": "cpp" }, { "name": "Motor Control With Encoder", @@ -19,7 +21,9 @@ "Actuators", "Joystick", "Complete List" - ] + ], + "foldername": "MotorControlEncoder", + "gradlebase": "cpp" }, { "name": "Relay", @@ -28,7 +32,9 @@ "Actuators", "Joystick", "Complete List" - ] + ], + "foldername": "Relay", + "gradlebase": "cpp" }, { "name": "PDP CAN Monitoring", @@ -37,7 +43,9 @@ "Complete List", "CAN", "Sensors" - ] + ], + "foldername": "CANPDP", + "gradlebase": "cpp" }, { "name": "Solenoids", @@ -47,7 +55,9 @@ "Joystick", "Pneumatics", "Complete List" - ] + ], + "foldername": "Solenoid", + "gradlebase": "cpp" }, { "name": "Encoder", @@ -56,7 +66,9 @@ "Complete List", "Digital", "Sensors" - ] + ], + "foldername": "Encoder", + "gradlebase": "cpp" }, { "name": "Arcade Drive", @@ -66,7 +78,9 @@ "Robot and Motor", "Joystick", "Complete List" - ] + ], + "foldername": "ArcadeDrive", + "gradlebase": "cpp" }, { "name": "Mecanum Drive", @@ -76,7 +90,9 @@ "Robot and Motor", "Joystick", "Complete List" - ] + ], + "foldername": "MecanumDrive", + "gradlebase": "cpp" }, { "name": "Ultrasonic", @@ -86,7 +102,9 @@ "Complete List", "Sensors", "Analog" - ] + ], + "foldername": "Ultrasonic", + "gradlebase": "cpp" }, { "name": "UltrasonicPID", @@ -96,7 +114,9 @@ "Complete List", "Sensors", "Analog" - ] + ], + "foldername": "UltrasonicPID", + "gradlebase": "cpp" }, { "name": "Gyro", @@ -107,7 +127,9 @@ "Sensors", "Analog", "Joystick" - ] + ], + "foldername": "Gyro", + "gradlebase": "cpp" }, { "name": "Gyro Mecanum", @@ -118,7 +140,9 @@ "Sensors", "Analog", "Joysitck" - ] + ], + "foldername": "GyroMecanum", + "gradlebase": "cpp" }, { "name": "PotentiometerPID", @@ -129,7 +153,9 @@ "Complete List", "Sensors", "Analog" - ] + ], + "foldername": "PotentiometerPID", + "gradlebase": "cpp" }, { "name": "Getting Started", @@ -137,7 +163,9 @@ "tags": [ "Getting Started with C++", "Complete List" - ] + ], + "foldername": "GettingStarted", + "gradlebase": "cpp" }, { "name": "Simple Vision", @@ -145,7 +173,9 @@ "tags": [ "Vision", "Complete List" - ] + ], + "foldername": "QuickVision", + "gradlebase": "cpp" }, { "name": "Intermediate Vision", @@ -153,7 +183,9 @@ "tags": [ "Vision", "Complete List" - ] + ], + "foldername": "IntermediateVision", + "gradlebase": "cpp" }, { "name": "Axis Camera Sample", @@ -161,7 +193,9 @@ "tags": [ "Vision", "Complete List" - ] + ], + "foldername": "AxisCameraSample", + "gradlebase": "cpp" }, { "name": "GearsBot", @@ -169,7 +203,9 @@ "tags": [ "CommandBased Robot", "Complete List" - ] + ], + "foldername": "GearsBot", + "gradlebase": "cpp" }, { "name": "PacGoat", @@ -177,6 +213,8 @@ "tags": [ "CommandBased Robot", "Complete List" - ] + ], + "foldername": "PacGoat", + "gradlebase": "cpp" } ] diff --git a/wpilibcExamples/src/main/cpp/templates/templates.json b/wpilibcExamples/src/main/cpp/templates/templates.json index ab49ca29f3..147eb85487 100644 --- a/wpilibcExamples/src/main/cpp/templates/templates.json +++ b/wpilibcExamples/src/main/cpp/templates/templates.json @@ -5,7 +5,8 @@ "tags": [ "Iterative" ], - "foldername": "iterative" + "foldername": "iterative", + "gradlebase": "cpp" }, { "name": "Timed Robot", @@ -13,7 +14,8 @@ "tags": [ "Timed" ], - "foldername": "timed" + "foldername": "timed", + "gradlebase": "cpp" }, { "name": "Command Robot", @@ -21,7 +23,8 @@ "tags": [ "Command" ], - "foldername": "commandbased" + "foldername": "commandbased", + "gradlebase": "cpp" }, { "name": "Sample Robot", @@ -29,6 +32,7 @@ "tags": [ "Sample" ], - "foldername": "sample" + "foldername": "sample", + "gradlebase": "cpp" } ] diff --git a/wpilibjExamples/build.gradle b/wpilibjExamples/build.gradle index 34b68dcad2..55087ba754 100644 --- a/wpilibjExamples/build.gradle +++ b/wpilibjExamples/build.gradle @@ -35,3 +35,14 @@ gradle.projectsEvaluated { } apply from: 'publish.gradle' + +ext { + templateDirectory = new File("$projectDir/src/main/java/edu/wpi/first/wpilibj/templates/") + templateFile = new File("$projectDir/src/main/java/edu/wpi/first/wpilibj/templates/templates.json") + exampleDirectory = new File("$projectDir/src/main/java/edu/wpi/first/wpilibj/examples/") + exampleFile = new File("$projectDir/src/main/java/edu/wpi/first/wpilibj/examples/examples.json") + commandDirectory = new File("$projectDir/src/main/java/edu/wpi/first/wpilibj/commands/") + commandFile = new File("$projectDir/src/main/java/edu/wpi/first/wpilibj/commands/commands.json") +} + +apply from: "${rootDir}/shared/examplecheck.gradle" diff --git a/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/examples/examples.json b/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/examples/examples.json index 84cc0d55d8..51e44b2c21 100644 --- a/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/examples/examples.json +++ b/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/examples/examples.json @@ -5,7 +5,8 @@ "tags": [ "Getting Started with Java" ], - "foldername": "gettingstarted" + "foldername": "gettingstarted", + "gradlebase": "java" }, { "name": "Tank Drive", @@ -16,7 +17,8 @@ "Robot and Motor", "Safety" ], - "foldername": "tankdrive" + "foldername": "tankdrive", + "gradlebase": "java" }, { "name": "Mecanum Drive", @@ -27,7 +29,8 @@ "Robot and Motor", "Safety" ], - "foldername": "mecanumdrive" + "foldername": "mecanumdrive", + "gradlebase": "java" }, { "name": "Ultrasonic", @@ -37,7 +40,8 @@ "Robot and Motor", "Analog" ], - "foldername": "ultrasonic" + "foldername": "ultrasonic", + "gradlebase": "java" }, { "name": "Ultrasonic PID", @@ -47,7 +51,8 @@ "Robot and Motor", "Analog" ], - "foldername": "ultrasonicpid" + "foldername": "ultrasonicpid", + "gradlebase": "java" }, { "name": "Potentiometer PID", @@ -58,7 +63,8 @@ "Analog", "Joystick" ], - "foldername": "potentiometerpid" + "foldername": "potentiometerpid", + "gradlebase": "java" }, { "name": "Gyro", @@ -69,7 +75,8 @@ "Analog", "Joystick" ], - "foldername": "gyro" + "foldername": "gyro", + "gradlebase": "java" }, { "name": "Gyro Mecanum", @@ -80,7 +87,8 @@ "Analog", "Joystick" ], - "foldername": "gyromecanum" + "foldername": "gyromecanum", + "gradlebase": "java" }, { "name": "Motor Controller", @@ -90,7 +98,22 @@ "Joystick", "Robot and Motor" ], - "foldername": "motorcontrol" + "foldername": "motorcontrol", + "gradlebase": "java" + }, + { + "name": "Motor Control With Encoder", + "description": "Demonstrate controlling a single motor with a Joystick and displaying the net movement of the motor using an encoder.", + "tags": [ + "Robot and Motor", + "Digital", + "Sensors", + "Actuators", + "Joystick", + "Complete List" + ], + "foldername": "motorcontrolencoder", + "gradlebase": "java" }, { "name": "GearsBot", @@ -98,7 +121,8 @@ "tags": [ "Complete Robot" ], - "foldername": "gearsbot" + "foldername": "gearsbot", + "gradlebase": "java" }, { "name": "PacGoat", @@ -106,7 +130,8 @@ "tags": [ "Complete Robot" ], - "foldername": "pacgoat" + "foldername": "pacgoat", + "gradlebase": "java" }, { "name": "Simple Vision", @@ -115,7 +140,8 @@ "Vision", "Complete List" ], - "foldername": "simplevision" + "foldername": "quickvision", + "gradlebase": "java" }, { "name": "Intermediate Vision", @@ -124,7 +150,8 @@ "Vision", "Complete List" ], - "foldername": "intermediatevision" + "foldername": "intermediatevision", + "gradlebase": "java" }, { "name": "Axis Camera Sample", @@ -132,6 +159,7 @@ "tags": [ "Vision" ], - "foldername": "axiscamera" + "foldername": "axiscamera", + "gradlebase": "java" } ] diff --git a/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/examples/motorcontrolencoder/Robot.java b/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/examples/motorcontrolencoder/Robot.java new file mode 100644 index 0000000000..817f5fb191 --- /dev/null +++ b/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/examples/motorcontrolencoder/Robot.java @@ -0,0 +1,61 @@ +/*----------------------------------------------------------------------------*/ +/* Copyright (c) 2017-2018 FIRST. All Rights Reserved. */ +/* Open Source Software - may be modified and shared by FRC teams. The code */ +/* must be accompanied by the FIRST BSD license file in the root directory of */ +/* the project. */ +/*----------------------------------------------------------------------------*/ + +package edu.wpi.first.wpilibj.examples.motorcontrolencoder; + +import edu.wpi.first.wpilibj.Encoder; +import edu.wpi.first.wpilibj.IterativeRobot; +import edu.wpi.first.wpilibj.Joystick; +import edu.wpi.first.wpilibj.SpeedController; +import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; +import edu.wpi.first.wpilibj.Spark; + +/** + * This sample program shows how to control a motor using a joystick. In the + * operator control part of the program, the joystick is read and the value is + * written to the motor. + * + *

Joystick analog values range from -1 to 1 and speed controller inputs also + * range from -1 to 1 making it easy to work together. + * + *

In addition, the encoder value of an encoder connected to ports 0 and 1 is + * consistently sent to the Dashboard. + */ +public class Robot extends IterativeRobot { + private static final int kMotorPort = 0; + private static final int kJoystickPort = 0; + private static final int kEncoderPortA = 0; + private static final int kEncoderPortB = 1; + + private SpeedController m_motor; + private Joystick m_joystick; + private Encoder m_encoder; + + @Override + public void robotInit() { + m_motor = new Spark(kMotorPort); + m_joystick = new Joystick(kJoystickPort); + m_encoder = new Encoder(kEncoderPortA, kEncoderPortB); + // Use SetDistancePerPulse to set the multiplier for GetDistance + // This is set up assuming a 6 inch wheel with a 360 CPR encoder. + m_encoder.setDistancePerPulse((Math.PI * 6) / 360.0); + } + + /* + * The RobotPeriodic function is called every control packet no matter the + * robot mode. + */ + @Override + public void robotPeriodic() { + SmartDashboard.putNumber("Encoder", m_encoder.getDistance()); + } + + @Override + public void teleopPeriodic() { + m_motor.set(m_joystick.getY()); + } +} diff --git a/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/templates/templates.json b/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/templates/templates.json index ab49ca29f3..5db1283335 100644 --- a/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/templates/templates.json +++ b/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/templates/templates.json @@ -5,7 +5,8 @@ "tags": [ "Iterative" ], - "foldername": "iterative" + "foldername": "iterative", + "gradlebase": "java" }, { "name": "Timed Robot", @@ -13,7 +14,8 @@ "tags": [ "Timed" ], - "foldername": "timed" + "foldername": "timed", + "gradlebase": "java" }, { "name": "Command Robot", @@ -21,7 +23,8 @@ "tags": [ "Command" ], - "foldername": "commandbased" + "foldername": "commandbased", + "gradlebase": "java" }, { "name": "Sample Robot", @@ -29,6 +32,7 @@ "tags": [ "Sample" ], - "foldername": "sample" + "foldername": "sample", + "gradlebase": "java" } ]