From 63827dba58d5739560f9c1e31a8485d0781cb986 Mon Sep 17 00:00:00 2001 From: Eric Ratliff Date: Wed, 21 Jan 2026 08:00:25 -0600 Subject: [PATCH] Windows support included --- ftc-new-project.bat | 160 ++++++++++++++++++++++ windows/create-gradle-wrapper.bat | 117 ++++++++++++++++ windows/generate-build-gradle.bat | 56 ++++++++ windows/generate-build-script.bat | 56 ++++++++ windows/generate-deploy-script.bat | 192 +++++++++++++++++++++++++++ windows/generate-drive-subsystem.bat | 81 +++++++++++ windows/generate-drive-test.bat | 77 +++++++++++ windows/generate-gitignore.bat | 30 +++++ windows/generate-mecanum-drive.bat | 85 ++++++++++++ windows/generate-pose2d.bat | 37 ++++++ windows/generate-readme.bat | 132 ++++++++++++++++++ windows/generate-settings-gradle.bat | 17 +++ windows/generate-teleop.bat | 71 ++++++++++ windows/show-success.bat | 151 +++++++++++++++++++++ windows/show-usage.bat | 80 +++++++++++ 15 files changed, 1342 insertions(+) create mode 100644 ftc-new-project.bat create mode 100644 windows/create-gradle-wrapper.bat create mode 100644 windows/generate-build-gradle.bat create mode 100644 windows/generate-build-script.bat create mode 100644 windows/generate-deploy-script.bat create mode 100644 windows/generate-drive-subsystem.bat create mode 100644 windows/generate-drive-test.bat create mode 100644 windows/generate-gitignore.bat create mode 100644 windows/generate-mecanum-drive.bat create mode 100644 windows/generate-pose2d.bat create mode 100644 windows/generate-readme.bat create mode 100644 windows/generate-settings-gradle.bat create mode 100644 windows/generate-teleop.bat create mode 100644 windows/show-success.bat create mode 100644 windows/show-usage.bat diff --git a/ftc-new-project.bat b/ftc-new-project.bat new file mode 100644 index 0000000..19b1cf8 --- /dev/null +++ b/ftc-new-project.bat @@ -0,0 +1,160 @@ +@echo off +REM FTC Project Generator for Windows +REM Copyright (c) 2026 Nexus Workshops LLC +REM Licensed under MIT License + +setlocal enabledelayedexpansion + +REM Set default values +set "DEFAULT_FTC_VERSION=v10.1.1" +set "FTC_VERSION=%DEFAULT_FTC_VERSION%" +if not defined FTC_SDK_DIR set "FTC_SDK_DIR=%USERPROFILE%\ftc-sdk" + +REM Get script directory +set "SCRIPT_DIR=%~dp0" +set "WINDOWS_DIR=%SCRIPT_DIR%windows" + +REM Parse command line arguments +set "PROJECT_NAME=" +set "SHOW_HELP=0" + +:parse_args +if "%~1"=="" goto args_done +if /i "%~1"=="-h" set "SHOW_HELP=1" & goto next_arg +if /i "%~1"=="--help" set "SHOW_HELP=1" & goto next_arg +if /i "%~1"=="-v" set "FTC_VERSION=%~2" & shift & goto next_arg +if /i "%~1"=="--version" set "FTC_VERSION=%~2" & shift & goto next_arg +if /i "%~1"=="-d" set "FTC_SDK_DIR=%~2" & shift & goto next_arg +if /i "%~1"=="--sdk-dir" set "FTC_SDK_DIR=%~2" & shift & goto next_arg +if "%PROJECT_NAME%"=="" set "PROJECT_NAME=%~1" +:next_arg +shift +goto parse_args + +:args_done + +REM Show help if requested +if %SHOW_HELP%==1 ( + call "%WINDOWS_DIR%\show-usage.bat" + exit /b 0 +) + +REM Validate project name +if "%PROJECT_NAME%"=="" ( + echo Error: Project name required + echo Usage: %~nx0 ^ [options] + echo Run '%~nx0 --help' for more info + exit /b 1 +) + +set "PROJECT_DIR=%CD%\%PROJECT_NAME%" + +echo ============================================ +echo FTC Project Generator +echo ============================================ +echo Project: %PROJECT_NAME% +echo SDK Dir: %FTC_SDK_DIR% +echo SDK Version: %FTC_VERSION% +echo Target: %PROJECT_DIR% +echo. + +REM Step 1: Check/setup FTC SDK +echo ^>^>^> Checking FTC SDK... + +if exist "%FTC_SDK_DIR%" ( + echo SDK directory exists, checking version... + cd /d "%FTC_SDK_DIR%" + + if exist ".git" ( + REM Check current version + for /f "delims=" %%i in ('git describe --tags --exact-match 2^>nul') do set "CURRENT_TAG=%%i" + if "!CURRENT_TAG!"=="" set "CURRENT_TAG=none" + + if "!CURRENT_TAG!"=="%FTC_VERSION%" ( + echo + SDK already at version %FTC_VERSION% + ) else ( + echo Current version: !CURRENT_TAG! + echo Fetching and checking out %FTC_VERSION%... + git fetch --tags + git checkout "%FTC_VERSION%" + if errorlevel 1 ( + echo Error: Failed to checkout version %FTC_VERSION% + exit /b 1 + ) + echo + Updated to %FTC_VERSION% + ) + ) else ( + echo Warning: SDK directory exists but is not a git repo + echo Using existing directory anyway... + ) +) else ( + echo Cloning FTC SDK %FTC_VERSION%... + echo This will take a minute (SDK is ~200MB)... + git clone --depth 1 --branch "%FTC_VERSION%" https://github.com/FIRST-Tech-Challenge/FtcRobotController.git "%FTC_SDK_DIR%" + if errorlevel 1 ( + echo Error: Failed to clone FTC SDK + echo Check your internet connection or try a different version tag + exit /b 1 + ) + echo + Cloned FTC SDK %FTC_VERSION% to %FTC_SDK_DIR% +) + +REM Step 2: Create project structure +echo. +echo ^>^>^> Creating project: %PROJECT_NAME% + +if exist "%PROJECT_DIR%" ( + echo Error: Project directory already exists: %PROJECT_DIR% + exit /b 1 +) + +mkdir "%PROJECT_DIR%" +cd /d "%PROJECT_DIR%" + +REM Create directory structure +mkdir src\main\java\robot\subsystems 2>nul +mkdir src\main\java\robot\hardware 2>nul +mkdir src\main\java\robot\opmodes 2>nul +mkdir src\test\java\robot\subsystems 2>nul +mkdir src\test\java\robot\hardware 2>nul + +REM Step 3: Generate build files +echo Generating build configuration... +call "%WINDOWS_DIR%\generate-build-gradle.bat" "%PROJECT_DIR%" +call "%WINDOWS_DIR%\generate-settings-gradle.bat" "%PROJECT_DIR%" "%FTC_SDK_DIR%" + +REM Step 4: Create Gradle wrapper files +echo Setting up Gradle wrapper... +call "%WINDOWS_DIR%\create-gradle-wrapper.bat" "%PROJECT_DIR%" + +REM Step 5: Generate source files +echo Generating example source files... +call "%WINDOWS_DIR%\generate-pose2d.bat" "%PROJECT_DIR%" +call "%WINDOWS_DIR%\generate-drive-subsystem.bat" "%PROJECT_DIR%" +call "%WINDOWS_DIR%\generate-mecanum-drive.bat" "%PROJECT_DIR%" +call "%WINDOWS_DIR%\generate-teleop.bat" "%PROJECT_DIR%" +call "%WINDOWS_DIR%\generate-drive-test.bat" "%PROJECT_DIR%" + +REM Step 6: Generate helper scripts +echo Creating helper scripts... +call "%WINDOWS_DIR%\generate-build-script.bat" "%PROJECT_DIR%" +call "%WINDOWS_DIR%\generate-deploy-script.bat" "%PROJECT_DIR%" + +REM Step 7: Create project files +echo Creating project files... +call "%WINDOWS_DIR%\generate-gitignore.bat" "%PROJECT_DIR%" +call "%WINDOWS_DIR%\generate-readme.bat" "%PROJECT_DIR%" "%PROJECT_NAME%" + +REM Step 8: Initialize Git repository +echo. +echo ^>^>^> Initializing Git repository... +git init >nul 2>&1 +git add . >nul 2>&1 +git commit -m "Initial commit from FTC Project Generator" >nul 2>&1 +echo + Git repository initialized + +REM Final success message +call "%WINDOWS_DIR%\show-success.bat" "%PROJECT_NAME%" "%PROJECT_DIR%" "%FTC_SDK_DIR%" "%FTC_VERSION%" + +endlocal +exit /b 0 \ No newline at end of file diff --git a/windows/create-gradle-wrapper.bat b/windows/create-gradle-wrapper.bat new file mode 100644 index 0000000..c341635 --- /dev/null +++ b/windows/create-gradle-wrapper.bat @@ -0,0 +1,117 @@ +@echo off +REM Create Gradle wrapper files +setlocal + +set "PROJECT_DIR=%~1" + +REM Create gradle wrapper directory +mkdir "%PROJECT_DIR%\gradle\wrapper" 2>nul + +REM Create gradle-wrapper.properties +( +echo distributionBase=GRADLE_USER_HOME +echo distributionPath=wrapper/dists +echo distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +echo networkTimeout=10000 +echo zipStoreBase=GRADLE_USER_HOME +echo zipStorePath=wrapper/dists +) > "%PROJECT_DIR%\gradle\wrapper\gradle-wrapper.properties" + +REM Create gradlew.bat +( +echo @rem +echo @rem Copyright 2015 the original author or authors. +echo @rem +echo @rem Licensed under the Apache License, Version 2.0 ^(the "License"^); +echo @rem you may not use this file except in compliance with the License. +echo @rem You may obtain a copy of the License at +echo @rem +echo @rem https://www.apache.org/licenses/LICENSE-2.0 +echo @rem +echo @rem Unless required by applicable law or agreed to in writing, software +echo @rem distributed under the License is distributed on an "AS IS" BASIS, +echo @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +echo @rem See the License for the specific language governing permissions and +echo @rem limitations under the License. +echo @rem +echo. +echo @if "%%DEBUG%%"=="" @echo off +echo @rem ########################################################################## +echo @rem +echo @rem Gradle startup script for Windows +echo @rem +echo @rem ########################################################################## +echo. +echo @rem Set local scope for the variables with windows NT shell +echo if "%%OS%%"=="Windows_NT" setlocal +echo. +echo set DIRNAME=%%~dp0 +echo if "%%DIRNAME%%"=="" set DIRNAME=. +echo set APP_BASE_NAME=%%~n0 +echo set APP_HOME=%%DIRNAME%% +echo. +echo @rem Resolve any "." and ".." in APP_HOME to make it shorter. +echo for %%%%i in ^("%%APP_HOME%%"^) do set APP_HOME=%%%%~fi +echo. +echo @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +echo set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" +echo. +echo @rem Find java.exe +echo if defined JAVA_HOME goto findJavaFromJavaHome +echo. +echo set JAVA_EXE=java.exe +echo %%JAVA_EXE%% -version ^>NUL 2^>^&1 +echo if "%%ERRORLEVEL%%"=="0" goto execute +echo. +echo echo. +echo echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo echo. +echo echo Please set the JAVA_HOME variable in your environment to match the +echo echo location of your Java installation. +echo. +echo goto fail +echo. +echo :findJavaFromJavaHome +echo set JAVA_HOME=%%JAVA_HOME:"=%% +echo set JAVA_EXE=%%JAVA_HOME%%/bin/java.exe +echo. +echo if exist "%%JAVA_EXE%%" goto execute +echo. +echo echo. +echo echo ERROR: JAVA_HOME is set to an invalid directory: %%JAVA_HOME%% +echo echo. +echo echo Please set the JAVA_HOME variable in your environment to match the +echo echo location of your Java installation. +echo. +echo goto fail +echo. +echo :execute +echo @rem Setup the command line +echo. +echo set CLASSPATH=%%APP_HOME%%\gradle\wrapper\gradle-wrapper.jar +echo. +echo @rem Execute Gradle +echo "%%JAVA_EXE%%" %%DEFAULT_JVM_OPTS%% %%JAVA_OPTS%% %%GRADLE_OPTS%% "-Dorg.gradle.appname=%%APP_BASE_NAME%%" -classpath "%%CLASSPATH%%" org.gradle.wrapper.GradleWrapperMain %%* +echo. +echo :end +echo @rem End local scope for the variables with windows NT shell +echo if "%%ERRORLEVEL%%"=="0" goto mainEnd +echo. +echo :fail +echo rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +echo rem the _cmd.exe /c_ return code! +echo if not "" == "%%GRADLE_EXIT_CONSOLE%%" exit 1 +echo exit /b 1 +echo. +echo :mainEnd +echo if "%%OS%%"=="Windows_NT" endlocal +echo. +echo :omega +) > "%PROJECT_DIR%\gradlew.bat" + +REM Create minimal gradle-wrapper.jar placeholder message +echo Note: Download gradle-wrapper.jar from https://services.gradle.org/distributions/ > "%PROJECT_DIR%\gradle\wrapper\gradle-wrapper.jar.txt" +echo Or run: gradlew wrapper to generate the complete wrapper >> "%PROJECT_DIR%\gradle\wrapper\gradle-wrapper.jar.txt" + +endlocal +exit /b 0 \ No newline at end of file diff --git a/windows/generate-build-gradle.bat b/windows/generate-build-gradle.bat new file mode 100644 index 0000000..8f3b8a6 --- /dev/null +++ b/windows/generate-build-gradle.bat @@ -0,0 +1,56 @@ +@echo off +REM Generate build.gradle.kts file +setlocal + +set "PROJECT_DIR=%~1" + +( +echo plugins { +echo java +echo } +echo. +echo repositories { +echo mavenCentral^(^) +echo google^(^) +echo } +echo. +echo dependencies { +echo // Testing ^(runs on PC without SDK^) +echo testImplementation^("org.junit.jupiter:junit-jupiter:5.10.0"^) +echo testRuntimeOnly^("org.junit.platform:junit-platform-launcher"^) +echo testImplementation^("org.mockito:mockito-core:5.5.0"^) +echo } +echo. +echo java { +echo sourceCompatibility = JavaVersion.VERSION_11 +echo targetCompatibility = JavaVersion.VERSION_11 +echo } +echo. +echo tasks.test { +echo useJUnitPlatform^(^) +echo testLogging { +echo events^("passed", "skipped", "failed"^) +echo showStandardStreams = false +echo exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL +echo } +echo } +echo. +echo // Task to deploy to FTC SDK +echo tasks.register^^("deployToSDK"^) { +echo group = "deployment" +echo description = "Deploy robot code to FTC SDK TeamCode module" +echo. +echo from^("src/main/java"^) { +echo include^("robot/**/*.java"^) +echo } +echo. +echo into^(layout.projectDirectory.dir^("../ftc-sdk/TeamCode/src/main/java"^)^) +echo. +echo doLast { +echo println^("Code deployed to TeamCode - ready to build APK"^) +echo } +echo } +) > "%PROJECT_DIR%\build.gradle.kts" + +endlocal +exit /b 0 \ No newline at end of file diff --git a/windows/generate-build-script.bat b/windows/generate-build-script.bat new file mode 100644 index 0000000..a143017 --- /dev/null +++ b/windows/generate-build-script.bat @@ -0,0 +1,56 @@ +@echo off +REM Generate build.bat helper script +setlocal + +set "PROJECT_DIR=%~1" + +( +echo @echo off +echo REM Quick build/check script for FTC project +echo. +echo setlocal +echo. +echo set CLEAN=0 +echo. +echo :parse_args +echo if "%%~1"=="" goto args_done +echo if /i "%%~1"=="--clean" set CLEAN=1 +echo if /i "%%~1"=="-c" set CLEAN=1 +echo shift +echo goto parse_args +echo. +echo :args_done +echo. +echo if %%CLEAN%%==1 ^( +echo echo Cleaning build... +echo call gradlew clean +echo ^) +echo. +echo echo Building and testing... +echo call gradlew build test +echo. +echo if errorlevel 1 ^( +echo echo. +echo echo Build FAILED - check errors above +echo exit /b 1 +echo ^) +echo. +echo echo. +echo echo ================================================================ +echo echo Build Successful! +echo echo ================================================================ +echo echo. +echo echo Your code compiles and all tests pass. +echo echo Ready to deploy to robot when you are. +echo echo. +echo echo Next steps: +echo echo 1. Uncomment FTC imports in hardware and opmodes +echo echo 2. Run: deploy-to-robot.bat +echo echo. +echo. +echo endlocal +echo exit /b 0 +) > "%PROJECT_DIR%\build.bat" + +endlocal +exit /b 0 \ No newline at end of file diff --git a/windows/generate-deploy-script.bat b/windows/generate-deploy-script.bat new file mode 100644 index 0000000..00da9cb --- /dev/null +++ b/windows/generate-deploy-script.bat @@ -0,0 +1,192 @@ +@echo off +REM Generate deploy-to-robot.bat script +setlocal + +set "PROJECT_DIR=%~1" + +( +echo @echo off +echo REM Deploy FTC project to Control Hub +echo. +echo setlocal enabledelayedexpansion +echo. +echo set "CONTROL_HUB_IP=192.168.43.1" +echo set "CONTROL_HUB_PORT=5555" +echo set "FORCE_USB=0" +echo set "FORCE_WIFI=0" +echo set "SHOW_HELP=0" +echo. +echo :parse_args +echo if "%%~1"=="" goto args_done +echo if /i "%%~1"=="-h" set "SHOW_HELP=1" ^& goto next_arg +echo if /i "%%~1"=="--help" set "SHOW_HELP=1" ^& goto next_arg +echo if /i "%%~1"=="--usb" set "FORCE_USB=1" ^& goto next_arg +echo if /i "%%~1"=="--wifi" set "FORCE_WIFI=1" ^& goto next_arg +echo if /i "%%~1"=="-i" set "CONTROL_HUB_IP=%%~2" ^& shift ^& goto next_arg +echo if /i "%%~1"=="--ip" set "CONTROL_HUB_IP=%%~2" ^& shift ^& goto next_arg +echo :next_arg +echo shift +echo goto parse_args +echo. +echo :args_done +echo. +echo if %%SHOW_HELP%%==1 ^( +echo echo ================================================================ +echo echo FTC Project Deployment - Deploy to Robot +echo echo ================================================================ +echo echo. +echo echo Deploys your robot code to the Control Hub and installs APK. +echo echo. +echo echo USAGE: +echo echo deploy-to-robot.bat [options] +echo echo. +echo echo OPTIONS: +echo echo --usb Force USB connection +echo echo --wifi Force WiFi Direct connection +echo echo -i, --ip ^ Custom Control Hub IP +echo echo -h, --help Show this help +echo echo. +echo echo EXAMPLES: +echo echo deploy-to-robot.bat Auto-detect connection +echo echo deploy-to-robot.bat --usb Use USB only +echo echo deploy-to-robot.bat --wifi Use WiFi Direct +echo echo deploy-to-robot.bat -i 192.168.1.100 Custom IP +echo echo. +echo exit /b 0 +echo ^) +echo. +echo echo ================================================================ +echo echo FTC Project Deployment - Deploy to Robot +echo echo ================================================================ +echo echo. +echo. +echo echo Step 1: Deploying code to SDK TeamCode... +echo call gradlew deployToSDK +echo if errorlevel 1 ^( +echo echo Error: Failed to deploy code +echo exit /b 1 +echo ^) +echo echo + Code deployed +echo echo. +echo. +echo echo Step 2: Building APK... +echo cd /d "%%USERPROFILE%%\ftc-sdk" +echo if not exist "%%CD%%\build.gradle" ^( +echo echo Error: FTC SDK not found at %%USERPROFILE%%\ftc-sdk +echo exit /b 1 +echo ^) +echo. +echo call gradlew build +echo if errorlevel 1 ^( +echo echo Error: APK build failed +echo exit /b 1 +echo ^) +echo. +echo set "APK_PATH=%%CD%%\FtcRobotController\build\outputs\apk\debug\FtcRobotController-debug.apk" +echo if not exist "!APK_PATH!" ^( +echo echo Error: APK not found at expected location +echo echo Expected: !APK_PATH! +echo exit /b 1 +echo ^) +echo echo + APK built successfully +echo echo. +echo. +echo echo Step 3: Installing to Control Hub... +echo echo. +echo. +echo where adb ^>nul 2^>^&1 +echo if errorlevel 1 ^( +echo echo Error: 'adb' not found in PATH +echo echo. +echo echo Install Android SDK Platform Tools and add to PATH: +echo echo https://developer.android.com/studio/releases/platform-tools +echo echo. +echo exit /b 1 +echo ^) +echo. +echo set "INSTALLED=0" +echo. +echo REM Try USB first +echo if %%FORCE_WIFI%%==0 ^( +echo echo Checking for USB connection... +echo for /f "delims=" %%%%i in ^('adb devices ^| find "device" ^| find /v "List"'^) do set USB_FOUND=1 +echo. +echo if defined USB_FOUND ^( +echo echo + Control Hub connected via USB +echo echo. +echo adb install -r "!APK_PATH!" +echo if not errorlevel 1 set "INSTALLED=1" +echo ^) else ^( +echo if %%FORCE_USB%%==1 ^( +echo echo Error: No USB device found +echo echo Make sure Control Hub is connected and USB debugging is enabled +echo exit /b 1 +echo ^) else ^( +echo echo No USB device detected +echo ^) +echo ^) +echo ^) +echo. +echo REM Try WiFi if USB didn't work +echo if "!INSTALLED!"=="0" if %%FORCE_USB%%==0 ^( +echo echo Trying WiFi connection to %%CONTROL_HUB_IP%%:%%CONTROL_HUB_PORT%%... +echo echo. +echo. +echo adb connect %%CONTROL_HUB_IP%%:%%CONTROL_HUB_PORT%% ^>nul 2^>^&1 +echo timeout /t 2 /nobreak ^>nul +echo. +echo adb devices ^| find "%%CONTROL_HUB_IP%%" ^>nul +echo if not errorlevel 1 ^( +echo echo + Connected via WiFi +echo echo. +echo adb install -r "!APK_PATH!" +echo if not errorlevel 1 set "INSTALLED=1" +echo ^) +echo ^) +echo. +echo if "!INSTALLED!"=="0" ^( +echo echo. +echo echo ================================================================ +echo echo Could not connect to Control Hub +echo echo ================================================================ +echo echo. +echo echo Connection options: +echo echo. +echo echo 1. USB Connection ^(Recommended^) +echo echo - Plug Control Hub into computer with USB cable +echo echo - Run: deploy-to-robot.bat --usb +echo echo. +echo echo 2. WiFi Direct Connection +echo echo - Connect to 'FIRST-xxxx-RC' network +echo echo - Run: deploy-to-robot.bat --wifi +echo echo. +echo echo 3. Custom Network +echo echo - Find Control Hub IP on your network +echo echo - Run: deploy-to-robot.bat -i YOUR_IP +echo echo. +echo echo 4. Manual Install +echo echo - APK built at: !APK_PATH! +echo echo - Use Android Studio to deploy +echo echo. +echo exit /b 1 +echo ^) +echo. +echo echo. +echo echo ================================================================ +echo echo + Deployment Complete! +echo echo ================================================================ +echo echo. +echo echo On Driver Station: +echo echo 1. Go to: OpModes menu +echo echo 2. Select: TeleOp -^> 'Main TeleOp' +echo echo 3. Press: INIT, then START +echo echo. +echo echo Your code is now running on the robot! 🤖 +echo echo. +echo. +echo endlocal +echo exit /b 0 +) > "%PROJECT_DIR%\deploy-to-robot.bat" + +endlocal +exit /b 0 \ No newline at end of file diff --git a/windows/generate-drive-subsystem.bat b/windows/generate-drive-subsystem.bat new file mode 100644 index 0000000..d1cec81 --- /dev/null +++ b/windows/generate-drive-subsystem.bat @@ -0,0 +1,81 @@ +@echo off +REM Generate Drive.java subsystem +setlocal + +set "PROJECT_DIR=%~1" + +( +echo package robot.subsystems; +echo. +echo import robot.Pose2d; +echo. +echo /** +echo * Drive subsystem - business logic only. +echo * Hardware interface defined as inner interface. +echo * Tests use inline mocks - no FTC SDK needed. +echo */ +echo public class Drive { +echo private final Hardware hardware; +echo private Pose2d pose; +echo. +echo public Drive^(Hardware hardware^) { +echo this.hardware = hardware; +echo this.pose = new Pose2d^(^); +echo } +echo. +echo /** +echo * Drive using field-centric controls. +echo * @param forward Forward/backward speed ^(-1.0 to 1.0^) +echo * @param strafe Left/right speed ^(-1.0 to 1.0^) +echo * @param rotate Rotation speed ^(-1.0 to 1.0^) +echo */ +echo public void drive^(double forward, double strafe, double rotate^) { +echo // Your drive logic here +echo double heading = hardware.getHeading^(^); +echo. +echo // Example: field-centric conversion +echo double cos = Math.cos^(heading^); +echo double sin = Math.sin^(heading^); +echo. +echo double rotatedForward = forward * cos - strafe * sin; +echo double rotatedStrafe = forward * sin + strafe * cos; +echo. +echo hardware.setPowers^(rotatedForward, rotatedStrafe, rotate^); +echo } +echo. +echo /** +echo * Stop all drive motors. +echo */ +echo public void stop^(^) { +echo hardware.setPowers^(0, 0, 0^); +echo } +echo. +echo /** +echo * Get current estimated pose. +echo */ +echo public Pose2d getPose^(^) { +echo return pose; +echo } +echo. +echo /** +echo * Hardware interface - implement this for real robot. +echo */ +echo public interface Hardware { +echo /** +echo * Get robot heading in radians. +echo */ +echo double getHeading^(^); +echo. +echo /** +echo * Set drive motor powers. +echo * @param forward Forward power +echo * @param strafe Strafe power +echo * @param rotate Rotation power +echo */ +echo void setPowers^(double forward, double strafe, double rotate^); +echo } +echo } +) > "%PROJECT_DIR%\src\main\java\robot\subsystems\Drive.java" + +endlocal +exit /b 0 \ No newline at end of file diff --git a/windows/generate-drive-test.bat b/windows/generate-drive-test.bat new file mode 100644 index 0000000..d9e1a6e --- /dev/null +++ b/windows/generate-drive-test.bat @@ -0,0 +1,77 @@ +@echo off +REM Generate DriveTest.java +setlocal + +set "PROJECT_DIR=%~1" + +( +echo package robot.subsystems; +echo. +echo import org.junit.jupiter.api.Test; +echo import static org.junit.jupiter.api.Assertions.*; +echo. +echo /** +echo * Unit tests for Drive subsystem. +echo * Uses inline mock - no FTC SDK required. +echo */ +echo class DriveTest { +echo. +echo /** +echo * Simple mock implementation of Drive.Hardware. +echo * Captures method calls for verification in tests. +echo */ +echo static class MockHardware implements Drive.Hardware { +echo double lastForward = 0; +echo double lastStrafe = 0; +echo double lastRotate = 0; +echo double heading = 0; +echo int setPowersCallCount = 0; +echo. +echo @Override +echo public double getHeading^(^) { +echo return heading; +echo } +echo. +echo @Override +echo public void setPowers^(double forward, double strafe, double rotate^) { +echo this.lastForward = forward; +echo this.lastStrafe = strafe; +echo this.lastRotate = rotate; +echo this.setPowersCallCount++; +echo } +echo } +echo. +echo @Test +echo void testDriveCallsSetPowers^(^) { +echo MockHardware mock = new MockHardware^(^); +echo Drive drive = new Drive^(mock^); +echo. +echo drive.drive^(0.5, 0.3, 0.1^); +echo. +echo assertEquals^(1, mock.setPowersCallCount, "setPowers should be called once"^); +echo } +echo. +echo @Test +echo void testStopSetsZeroPower^(^) { +echo MockHardware mock = new MockHardware^(^); +echo Drive drive = new Drive^(mock^); +echo. +echo drive.stop^(^); +echo. +echo assertEquals^(0.0, mock.lastForward, 0.001^); +echo assertEquals^(0.0, mock.lastStrafe, 0.001^); +echo assertEquals^(0.0, mock.lastRotate, 0.001^); +echo } +echo. +echo @Test +echo void testGetPoseReturnsNonNull^(^) { +echo MockHardware mock = new MockHardware^(^); +echo Drive drive = new Drive^(mock^); +echo. +echo assertNotNull^(drive.getPose^(^), "Pose should never be null"^); +echo } +echo } +) > "%PROJECT_DIR%\src\test\java\robot\subsystems\DriveTest.java" + +endlocal +exit /b 0 \ No newline at end of file diff --git a/windows/generate-gitignore.bat b/windows/generate-gitignore.bat new file mode 100644 index 0000000..caff168 --- /dev/null +++ b/windows/generate-gitignore.bat @@ -0,0 +1,30 @@ +@echo off +REM Generate .gitignore file +setlocal + +set "PROJECT_DIR=%~1" + +( +echo # Gradle +echo .gradle/ +echo build/ +echo. +echo # IDE +echo .idea/ +echo *.iml +echo .vscode/ +echo. +echo # OS +echo .DS_Store +echo Thumbs.db +echo. +echo # Java +echo *.class +echo *.log +echo. +echo # Gradle wrapper jar +echo gradle/wrapper/gradle-wrapper.jar +) > "%PROJECT_DIR%\.gitignore" + +endlocal +exit /b 0 \ No newline at end of file diff --git a/windows/generate-mecanum-drive.bat b/windows/generate-mecanum-drive.bat new file mode 100644 index 0000000..ba034d5 --- /dev/null +++ b/windows/generate-mecanum-drive.bat @@ -0,0 +1,85 @@ +@echo off +REM Generate MecanumDrive.java hardware implementation +setlocal + +set "PROJECT_DIR=%~1" + +( +echo package robot.hardware; +echo. +echo import robot.subsystems.Drive; +echo. +echo // Uncomment when deploying to robot: +echo // import com.qualcomm.robotcore.hardware.DcMotor; +echo // import com.qualcomm.robotcore.hardware.HardwareMap; +echo // import com.qualcomm.robotcore.hardware.IMU; +echo // import org.firstinspires.ftc.robotcore.external.navigation.AngleUnit; +echo. +echo /** +echo * Mecanum drive hardware implementation. +echo * Implements Drive.Hardware interface. +echo * +echo * DEPLOYMENT NOTE: +echo * Uncomment FTC imports and implementation when ready to deploy. +echo * Keep commented during development/testing on PC. +echo */ +echo public class MecanumDrive implements Drive.Hardware { +echo. +echo // Uncomment when deploying: +echo // private final DcMotor frontLeft; +echo // private final DcMotor frontRight; +echo // private final DcMotor backLeft; +echo // private final DcMotor backRight; +echo // private final IMU imu; +echo. +echo public MecanumDrive^(/* HardwareMap hardwareMap */^) { +echo // Uncomment when deploying: +echo // frontLeft = hardwareMap.get^(DcMotor.class, "frontLeft"^); +echo // frontRight = hardwareMap.get^(DcMotor.class, "frontRight"^); +echo // backLeft = hardwareMap.get^(DcMotor.class, "backLeft"^); +echo // backRight = hardwareMap.get^(DcMotor.class, "backRight"^); +echo // imu = hardwareMap.get^(IMU.class, "imu"^); +echo // +echo // // Configure motors +echo // frontLeft.setZeroPowerBehavior^(DcMotor.ZeroPowerBehavior.BRAKE^); +echo // frontRight.setZeroPowerBehavior^(DcMotor.ZeroPowerBehavior.BRAKE^); +echo // backLeft.setZeroPowerBehavior^(DcMotor.ZeroPowerBehavior.BRAKE^); +echo // backRight.setZeroPowerBehavior^(DcMotor.ZeroPowerBehavior.BRAKE^); +echo } +echo. +echo @Override +echo public double getHeading^(^) { +echo // Stub for testing - returns 0 +echo return 0.0; +echo. +echo // Uncomment when deploying: +echo // return imu.getRobotYawPitchRollAngles^(^).getYaw^(AngleUnit.RADIANS^); +echo } +echo. +echo @Override +echo public void setPowers^(double forward, double strafe, double rotate^) { +echo // Stub for testing - does nothing +echo. +echo // Uncomment when deploying: +echo // // Mecanum drive kinematics +echo // double frontLeftPower = forward + strafe + rotate; +echo // double frontRightPower = forward - strafe - rotate; +echo // double backLeftPower = forward - strafe + rotate; +echo // double backRightPower = forward + strafe - rotate; +echo // +echo // // Normalize powers +echo // double maxPower = Math.max^(1.0, Math.max^( +echo // Math.max^(Math.abs^(frontLeftPower^), Math.abs^(frontRightPower^)^), +echo // Math.max^(Math.abs^(backLeftPower^), Math.abs^(backRightPower^)^) +echo // ^)^); +echo // +echo // frontLeft.setPower^(frontLeftPower / maxPower^); +echo // frontRight.setPower^(frontRightPower / maxPower^); +echo // backLeft.setPower^(backLeftPower / maxPower^); +echo // backRight.setPower^(backRightPower / maxPower^); +echo } +echo } +) > "%PROJECT_DIR%\src\main\java\robot\hardware\MecanumDrive.java" + +endlocal +exit /b 0 \ No newline at end of file diff --git a/windows/generate-pose2d.bat b/windows/generate-pose2d.bat new file mode 100644 index 0000000..fb0f2af --- /dev/null +++ b/windows/generate-pose2d.bat @@ -0,0 +1,37 @@ +@echo off +REM Generate Pose2d.java +setlocal + +set "PROJECT_DIR=%~1" + +( +echo package robot; +echo. +echo /** +echo * Simple 2D pose representation ^(x, y, heading^). +echo * Pure data class - no dependencies. +echo */ +echo public class Pose2d { +echo public final double x; +echo public final double y; +echo public final double heading; +echo. +echo public Pose2d^(double x, double y, double heading^) { +echo this.x = x; +echo this.y = y; +echo this.heading = heading; +echo } +echo. +echo public Pose2d^(^) { +echo this^(0, 0, 0^); +echo } +echo. +echo @Override +echo public String toString^(^) { +echo return String.format^("Pose2d^(x=%%.2f, y=%%.2f, heading=%%.2f^)", x, y, heading^); +echo } +echo } +) > "%PROJECT_DIR%\src\main\java\robot\Pose2d.java" + +endlocal +exit /b 0 \ No newline at end of file diff --git a/windows/generate-readme.bat b/windows/generate-readme.bat new file mode 100644 index 0000000..ab9f913 --- /dev/null +++ b/windows/generate-readme.bat @@ -0,0 +1,132 @@ +@echo off +REM Generate project README.md +setlocal + +set "PROJECT_DIR=%~1" +set "PROJECT_NAME=%~2" + +( +echo # %PROJECT_NAME% +echo. +echo FTC robot project generated by FTC Project Generator. +echo. +echo ## Quick Start +echo. +echo ```batch +echo REM Run tests +echo gradlew test +echo. +echo REM Watch tests ^(auto-rerun^) +echo gradlew test --continuous +echo. +echo REM Build and check +echo build.bat +echo. +echo REM Deploy to robot +echo deploy-to-robot.bat +echo ``` +echo. +echo ## Project Structure +echo. +echo ``` +echo %PROJECT_NAME%\ +echo +-- src\main\java\robot\ +echo ^| +-- subsystems\ Your robot logic ^(tested on PC^) +echo ^| +-- hardware\ FTC hardware implementations +echo ^| +-- opmodes\ FTC OpModes for Control Hub +echo +-- src\test\java\robot\ Unit tests ^(run without robot^) +echo ``` +echo. +echo ## Development Workflow +echo. +echo 1. **Write code** in `src/main/java/robot/` +echo 2. **Write tests** in `src/test/java/robot/` +echo 3. **Run tests** with `gradlew test --continuous` +echo 4. **Tests pass** → You're good! +echo. +echo ## Deployment to Robot +echo. +echo When ready to test on actual hardware: +echo. +echo 1. **Uncomment FTC imports** in: +echo - `src\main\java\robot\hardware\MecanumDrive.java` +echo - `src\main\java\robot\opmodes\TeleOp.java` +echo. +echo 2. **Run deployment script:** +echo ```batch +echo deploy-to-robot.bat +echo ``` +echo. +echo The script will: +echo - Deploy your code to SDK TeamCode +echo - Build APK +echo - Install to Control Hub ^(via USB or WiFi^) +echo. +echo ### Connection Methods +echo. +echo - **USB**: Just plug in and run ^(recommended^) +echo - **WiFi**: Connect to 'FIRST-xxxx-RC' network ^(IP: 192.168.43.1^) +echo - **Custom**: `deploy-to-robot.bat -i 192.168.1.x` +echo. +echo ## Adding New Subsystems +echo. +echo Follow the pattern: +echo. +echo 1. **Create subsystem** with inner Hardware interface: +echo ```java +echo public class MySubsystem { +echo public interface Hardware { +echo void doThing^(^); +echo } +echo } +echo ``` +echo. +echo 2. **Create test** with inline mock: +echo ```java +echo class MySubsystemTest { +echo static class MockHardware implements MySubsystem.Hardware { +echo boolean didThing = false; +echo public void doThing^(^) { didThing = true; } +echo } +echo } +echo ``` +echo. +echo 3. **Create hardware impl** for robot ^(keep FTC imports commented during dev^) +echo. +echo ## Tips +echo. +echo - Keep FTC imports commented during development +echo - Write tests for everything - they run instantly on PC +echo - Use `gradlew test --continuous` for fast iteration +echo - Multiple projects can share the same FTC SDK +echo. +echo ## Commands +echo. +echo ```batch +echo REM Development ^(on PC^) +echo gradlew test Run all tests +echo gradlew test --continuous Watch mode +echo. +echo REM Before deployment +echo build.bat Check for compile errors +echo build.bat --clean Clean build +echo. +echo REM Deploy to robot +echo deploy-to-robot.bat Full deployment +echo deploy-to-robot.bat --help Show options +echo. +echo REM Other +echo gradlew clean Clean build artifacts +echo gradlew tasks List available tasks +echo ``` +echo. +echo ## Generated by FTC Project Generator +echo. +echo This project structure separates your robot code from the FTC SDK, +echo making it easy to test on PC and deploy when ready. +echo. +echo For more information, see the FTC Project Generator documentation. +) > "%PROJECT_DIR%\README.md" + +endlocal +exit /b 0 \ No newline at end of file diff --git a/windows/generate-settings-gradle.bat b/windows/generate-settings-gradle.bat new file mode 100644 index 0000000..e2d6254 --- /dev/null +++ b/windows/generate-settings-gradle.bat @@ -0,0 +1,17 @@ +@echo off +REM Generate settings.gradle.kts file +setlocal + +set "PROJECT_DIR=%~1" +set "SDK_DIR=%~2" + +REM Convert Windows path to forward slashes for Gradle +set "SDK_PATH=%SDK_DIR:\=/%" + +( +echo // Include FTC SDK as composite build +echo includeBuild^("%SDK_PATH%"^) +) > "%PROJECT_DIR%\settings.gradle.kts" + +endlocal +exit /b 0 \ No newline at end of file diff --git a/windows/generate-teleop.bat b/windows/generate-teleop.bat new file mode 100644 index 0000000..9d93ccf --- /dev/null +++ b/windows/generate-teleop.bat @@ -0,0 +1,71 @@ +@echo off +REM Generate TeleOp.java OpMode +setlocal + +set "PROJECT_DIR=%~1" + +( +echo package robot.opmodes; +echo. +echo import robot.hardware.MecanumDrive; +echo import robot.subsystems.Drive; +echo. +echo // Uncomment when deploying to robot: +echo // import com.qualcomm.robotcore.eventloop.opmode.OpMode; +echo // import com.qualcomm.robotcore.eventloop.opmode.TeleOp; +echo. +echo /** +echo * Main TeleOp OpMode. +echo * +echo * DEPLOYMENT NOTE: +echo * Uncomment FTC imports and @TeleOp annotation when ready to deploy. +echo * Keep commented during development/testing on PC. +echo */ +echo // @TeleOp^(name="Main TeleOp"^) +echo public class TeleOp /* extends OpMode */ { +echo. +echo private Drive drive; +echo. +echo // Uncomment when deploying: +echo // @Override +echo public void init^(^) { +echo // Uncomment when deploying: +echo // MecanumDrive hardware = new MecanumDrive^(hardwareMap^); +echo // drive = new Drive^(hardware^); +echo // +echo // telemetry.addData^("Status", "Initialized"^); +echo // telemetry.update^(^); +echo } +echo. +echo // Uncomment when deploying: +echo // @Override +echo public void loop^(^) { +echo // Uncomment when deploying: +echo // // Get gamepad inputs +echo // double forward = -gamepad1.left_stick_y; // Inverted +echo // double strafe = gamepad1.left_stick_x; +echo // double rotate = gamepad1.right_stick_x; +echo // +echo // // Drive the robot +echo // drive.drive^(forward, strafe, rotate^); +echo // +echo // // Show telemetry +echo // telemetry.addData^("Forward", "%%.2f", forward^); +echo // telemetry.addData^("Strafe", "%%.2f", strafe^); +echo // telemetry.addData^("Rotate", "%%.2f", rotate^); +echo // telemetry.update^(^); +echo } +echo. +echo // Uncomment when deploying: +echo // @Override +echo public void stop^(^) { +echo // Uncomment when deploying: +echo // if ^(drive != null^) { +echo // drive.stop^(^); +echo // } +echo } +echo } +) > "%PROJECT_DIR%\src\main\java\robot\opmodes\TeleOp.java" + +endlocal +exit /b 0 \ No newline at end of file diff --git a/windows/show-success.bat b/windows/show-success.bat new file mode 100644 index 0000000..abb6ec7 --- /dev/null +++ b/windows/show-success.bat @@ -0,0 +1,151 @@ +@echo off +REM Display success message after project creation +setlocal + +set "PROJECT_NAME=%~1" +set "PROJECT_DIR=%~2" +set "FTC_SDK_DIR=%~3" +set "FTC_VERSION=%~4" + +echo. +echo ================================================================ +echo + Project Created! +echo ================================================================ +echo. +echo Project: %PROJECT_NAME% +echo Location: %PROJECT_DIR% +echo SDK: %FTC_SDK_DIR% ^(%FTC_VERSION%^) +echo Git: Initialized with initial commit +echo. +echo ================================================================ +echo QUICK START +echo ================================================================ +echo. +echo 1. Enter project and run tests: +echo cd %PROJECT_NAME% +echo gradlew test +echo. +echo 2. Watch tests ^(auto-rerun on save^): +echo gradlew test --continuous +echo. +echo ================================================================ +echo PROJECT STRUCTURE +echo ================================================================ +echo. +echo %PROJECT_NAME%\ +echo +-- src\main\java\robot\ +echo ^| +-- subsystems\ +echo ^| ^| +-- Drive.java ^<-- Your robot logic ^(EDIT THIS^) +echo ^| +-- hardware\ +echo ^| ^| +-- MecanumDrive.java ^<-- Hardware impl ^(EDIT THIS^) +echo ^| +-- opmodes\ +echo ^| +-- TeleOp.java ^<-- FTC OpMode ^(EDIT THIS^) +echo ^| +echo +-- src\test\java\robot\ +echo +-- subsystems\ +echo +-- DriveTest.java ^<-- Unit tests ^(ADD MORE^) +echo. +echo ================================================================ +echo DEVELOPMENT WORKFLOW +echo ================================================================ +echo. +echo Day-to-day development ^(on your PC^): +echo. +echo 1. Edit code in src\main\java\robot\ +echo 2. Edit tests in src\test\java\robot\ +echo 3. Run: gradlew test --continuous +echo 4. Tests pass -^> you're good! +echo. +echo Example: Add a new subsystem: +echo. +echo REM Create subsystem with inner Hardware interface +echo src\main\java\robot\subsystems\Intake.java +echo. +echo REM Create test with inline mock +echo src\test\java\robot\subsystems\IntakeTest.java +echo. +echo REM Run tests +echo gradlew test +echo. +echo ================================================================ +echo DEPLOYMENT TO ROBOT +echo ================================================================ +echo. +echo When ready to test on actual robot: +echo. +echo 1. Uncomment FTC imports in: +echo - src\main\java\robot\hardware\MecanumDrive.java +echo - src\main\java\robot\opmodes\TeleOp.java +echo. +echo 2. Run deployment script: +echo deploy-to-robot.bat +echo. +echo The script will: +echo + Deploy your code to SDK +echo + Build APK +echo + Install to Control Hub ^(via USB or WiFi^) +echo. +echo Connection methods: +echo - USB: Just plug in and run +echo - WiFi: Connect to 'FIRST-xxxx-RC' network ^(IP: 192.168.43.1^) +echo - Custom: set CONTROL_HUB_IP=192.168.1.x ^&^& deploy-to-robot.bat +echo. +echo ================================================================ +echo KEY FILES TO EDIT +echo ================================================================ +echo. +echo Start here: +echo. +echo src\main\java\robot\subsystems\Drive.java +echo -^> Your drive logic, tested on PC +echo. +echo src\main\java\robot\hardware\MecanumDrive.java +echo -^> Real motor control ^(uncomment FTC code when deploying^) +echo. +echo src\main\java\robot\opmodes\TeleOp.java +echo -^> Your main OpMode ^(uncomment FTC code when deploying^) +echo. +echo src\test\java\robot\subsystems\DriveTest.java +echo -^> Unit tests - add more as you build! +echo. +echo ================================================================ +echo USEFUL COMMANDS +echo ================================================================ +echo. +echo Development ^(on PC^): +echo gradlew test Run all tests +echo gradlew test --continuous Watch mode ^(auto-rerun^) +echo. +echo Before deployment: +echo build.bat Check for compile errors +echo build.bat --clean Clean build +echo. +echo Deploy to robot: +echo deploy-to-robot.bat Full deployment ^(build + install^) +echo deploy-to-robot.bat --help Show all deployment options +echo. +echo Other: +echo gradlew clean Clean build artifacts +echo gradlew tasks List all available tasks +echo. +echo ================================================================ +echo TIPS +echo ================================================================ +echo. +echo - Keep FTC imports commented during development +echo - Write tests for everything - they run instantly on PC +echo - Use 'gradlew test --continuous' for fast iteration +echo - See README.md for detailed documentation +echo - Multiple projects can share the same FTC SDK! +echo. +echo ================================================================ +echo. +echo Ready to start coding? Run: +echo. +echo cd %PROJECT_NAME% ^&^& gradlew test --continuous +echo. +echo Happy coding! 🤖 +echo. + +endlocal +exit /b 0 \ No newline at end of file diff --git a/windows/show-usage.bat b/windows/show-usage.bat new file mode 100644 index 0000000..58308f8 --- /dev/null +++ b/windows/show-usage.bat @@ -0,0 +1,80 @@ +@echo off +REM Display usage information for FTC Project Generator + +echo ================================================================ +echo FTC Project Generator - Clean Robot Projects +echo ================================================================ +echo. +echo Creates clean, testable FTC robot projects with shared SDK. +echo Your code stays separate - SDK is just a build dependency. +echo. +echo USAGE: +echo ftc-new-project ^ [options] +echo. +echo OPTIONS: +echo -v, --version ^ FTC SDK git tag (default: v10.1.1) +echo -d, --sdk-dir ^ SDK location (default: %%USERPROFILE%%\ftc-sdk) +echo -h, --help Show this help +echo. +echo EXAMPLES: +echo REM Create new project with latest SDK +echo ftc-new-project my-robot +echo. +echo REM Create project with specific FTC version +echo ftc-new-project competition-bot -v v10.0.0 +echo. +echo REM Use custom SDK location +echo ftc-new-project test-bot -d C:\my-ftc-sdk +echo. +echo REM Create second project (reuses existing SDK!) +echo ftc-new-project another-robot +echo. +echo WORKFLOW: +echo 1. Create project: ftc-new-project my-robot +echo 2. Develop ^& test: cd my-robot ^&^& gradlew test --continuous +echo 3. Deploy to SDK: gradlew deployToSDK +echo 4. Build APK: cd %%USERPROFILE%%\ftc-sdk ^&^& gradlew build +echo 5. Install to robot: Use Android Studio or adb +echo. +echo WHAT IT DOES: +echo + Checks/clones FTC SDK (shared across all projects) +echo + Creates YOUR clean project structure +echo + Generates test scaffolding with examples +echo + Sets up composite build to reference SDK +echo + Ready to code immediately +echo. +echo WHY THIS IS BETTER: +echo Traditional FTC: This Way: +echo - Clone 200MB repo - Your project: 50KB +echo - Your code mixed in - SDK separate, shared +echo - Hard to test - Tests run on PC instantly +echo - One repo per project - One SDK, many projects +echo - Forced BSD license - Your license, your code +echo. +echo ENVIRONMENT: +echo Set defaults to avoid typing them every time: +echo. +echo set FTC_SDK_DIR=%%USERPROFILE%%\ftc-sdk +echo set FTC_VERSION=v10.1.1 +echo. +echo PROJECT STRUCTURE: +echo my-robot\ +echo +-- src\main\java\robot\ +echo ^| +-- subsystems\ -^> Your robot logic (tested on PC) +echo ^| +-- hardware\ -^> FTC hardware implementations +echo ^| +-- opmodes\ -^> FTC OpModes for Control Hub +echo +-- src\test\java\robot\ -^> Unit tests (run without robot) +echo. +echo MULTIPLE PROJECTS: +echo One SDK, unlimited projects: +echo. +echo ftc-new-project swerve-bot REM Creates project 1 +echo ftc-new-project mecanum-bot REM Reuses SDK - just creates project 2 +echo ftc-new-project test-chassis REM Reuses SDK - creates project 3 +echo. +echo All projects share same SDK but are completely independent! +echo. +echo DOCUMENTATION: +echo See README.md for detailed information and examples. +echo. +exit /b 0 \ No newline at end of file