-
When writing your opmodes, always include the line
///@author <your-name>just above the@TeleOpor@Autonomousannotation. This provides clean documentation about who wrote the opmode, which is useful for collaborative purposes and knowing who to blame when something goes wrong. Jokes aside, it is very important when collaborating on code to sign your work.- Example:
///@author Josh Kelley @TeleOp(name = "My TeleOp") public class MyTeleOp extends TeleOpBase {...}
- Example:
-
If you are using the PlayStation controllers, use the button map below
PlayStation Gamepad(in code) X A O B △ Y □ X For example:
gamepad1.awill be automatically mapped to the X button on the PlayStation controller -
In TeleOp, the following buttons are in use by the
implementDriveLogic()method(gamepad1 only)left_stick_xleft_stick_yright_stick_xright_bumperleft_triggerright_trigger
by using these in your teleop code, that one action will control both the driving and whatever you mapped it to. If you want to change these, navigate to gcsrobotics/framework/TeleOpBase, and find theimplementDriveLogic(). There you can change all of the buttons.
All code is under TeamCode/src/main/java/gcsrobotics/. Here you will find 4 packages
examples: Example opmodes and programs that show how to use the framework for Autos and TeleOpsframework: The base code for methods and not opmode-specific code. You will only go here to change the Constants.java file and your hardware configuration in OpModeBase.javahardware: Hardware specific code for subsystems, wrappers and drivers. You will almost never need to interact with this package
opmodes: This is where your opmodes will reside. It is the only package where you can change anything and make it your owntuners: Opmodes for tuning hardware and debugging. You will generally not put anything in here unless you write an opmode to tune a specific subsystem
Setting up a new project is very easy, you only need to follow a few steps and you are ready to go!
- Fork the repo - go to the main GitHub page for this repo and look for the button that says Fork. Click that and give it a name
- Once you have done that, it should take you to a page that looks like the one for this repo, but with the name you gave it.
- Clone the repo(put the code onto your computer) - Click the green button that says Code on the main page of YOUR repository. Don't click that button on this page. Copy the URL you see there
- Go to Android Studio and click the top left three lines -> File -> New -> Project from Version Control. Paste in the URL you got in step 4 and continue
- It may take a few minutes to set up, but you will know you are ready when you see three folders in the left hand side of Android Studio;
FtcRobotController,TeamCode, andGradle Scripts - You're done! Remember, your code is under
TeamCode
This documentation covers all classes and methods in TeamCode/src/main/java/gcsrobotics/framework for the GreenlandRoboticsFramework.
It includes explanations for:
- What each method does
- How and why to use them
- Common usage scenarios
Purpose:
Abstract base for all OpModes (autonomous or teleop).
Handles hardware initialization and provides access to motors, servos, and odometry.
- Necessary
fl,fr,bl,br— Drivetrain motors (DcMotorEnhanced)odo— Odometry computer (GoBildaPinpointDriver)
- Examples(Not needed)
arm— Arm motor (DcMotorEnhanced)claw— Claw servo
These do exactly what they look like, return the x, y, or angle of the robot, respectively, according to the GoBilda Pinpoint. Having these in OpModeBase means you can call these methods in any Auto or TeleOp.
Initializes all hardware. You will need to modify this method for your specific robot. Look at the current one for examples
- Configures motor/servo objects, odometry, directions.
The following are internal methods. You won't interact with them or have to worry about them.
Override for code to run in init phase.
Override for code to run once start is pressed.
Main entrypoint for OpMode.
- Sets up telemetry, hardware, runs
runInit(), waits for start, then runsrun().
Purpose:
AutoBase is an abstract class for autonomous robot operation modes.
It extends OpModeBase, providing accurate movement utilities and control structures for writing robust autonomous routines.
- Extend
AutoBasein your own autonomous OpMode. - Override
initSequence()(optional) for initialization logic. - Override
runSequence()for your autonomous sequence. - Use movement methods like
path(),chain(),simpleDrive().
What does it mean to "Override" a function? Overriding just means implementing your own logic in a method, even if it is already defined. Here is what it looks like:
@Override //Not strictly needed but recommended for readability purposes
protected void predefinedMethod(){
// Example logic you might perform
doSomeTask()
doAnotherTask()
}The reason these are overriden is because they are already used by the parent class of the opmode, eg. AutoBase, but YOU have to tell it what that method actually does.
Override to add code you want to run in the init phase.
Example:
@Override
protected void initSequence(){
//Your init logic
}Override to define the autonomous actions (your main logic).
Moves the robot simply in the specified Axis at a set power for a duration. The options for Axis are Axis.X(forward & back) and Axis.Y(left & right)
- Use: For short, direct movements (e.g., nudging into position).
- Example:
simpleDrive(Axis.X, 0.5, 1000);
Sets all drive motors to the same power.
- Use: To move all wheels together, usually straight.
- Example:
setPowers(0.5)
Pauses execution for a number of milliseconds, updating odometry and telemetry.
- Use: Preferable to
sleep()in FTC, as it keeps robot feedback alive during the wait.
Accurate movement to a coordinate (targetX, targetY) with optional axis forgiveness.
- Use: For precise autonomous positioning.
forgiveAxis:Axis.XorAxis.Y. This is used if you don't care about a certain axis being totally accurate before moving on. This doesn't mean it doesn't move along that axis, but it is not a factor in when the path ends and moves onto the next piece of logic.- Example:
path(100,200)orpath(100,200,Axis.X)
Fast movement to a coordinate (less accurate than path).
- Use: When speed is more important than precision.
- Example:
chain(100,200)orchain(100,200,Axis.X)
Waits until a given condition is true.
- Use: For waiting on asynchronous events or sensor thresholds.
- Example:
waitUntil(() -> colorSensor.red() > 200). This is fake logic, but the idea is you put your condition right after the() ->
You don't need to worry about these, they are internal
pidDrivePower(double error, boolean isX)
Calculates PID-like drive power for pathing routines.setMotorPowers(double xPower, double yPower, double headingCorrection)
Sets individual wheel powers for advanced movement.sendTelemetry(String label, ...)Sends detailed telemetry for debugging pathing.stopMotors()Stops all drive motors.notStuck(double targetX, double targetY)Detects if the robot is stuck (not making progress).
Purpose:
Base for teleop OpModes.
Implements drive logic and framework for teleop control.
- Sets drivetrain motors to
RUN_WITHOUT_ENCODER(faster for teleop). - Calls
inInit()for your custom init code.
- Repeatedly calls
runLoop()while OpMode is active.
Override to add the main teleop loop logic.
Override to add code for the init phase of teleop.
- Set the drive speed multiplier.
- Example:
setSpeed(0.5) //Sets speed to half power
- Implements full mecanum drive logic using gamepads.
- Handles horizontal locking, slow mode, and trigger overrides.
- Use: Call this in your
runLoop()to handle all drive movement.
Purpose:
Central location for tunable constants (motor positions, PID values, setpoints, etc).
Example fields that many teams may use, feel free to delete them if they are unnecessary
clawClose,clawOpen: Servo positions for the claw.armUp,armMiddle,armDown: Encoder positions for arm levels.wristUp,wristDown: Servo positions for a wrist.
These fields are required, and are needed for basic functions. Do NOT delete these.ENCODER_TOLERANCE: How close an encoder must be to target to count as "there".KpDrive,KdDrive,KpTurn: PID coefficients for drive and turn control.autoMaxPower: Max drive power for autonomous.flDirection,frDirection,blDirection,brDirection: Motor directionsxPodDirection,yPodDirection: Direction of the GoBilda Pinpoint Odometry pods- All constants are static and can be tuned live with FTC Dashboard.
Purpose:
A wrapper around FTC's DcMotor providing easier position control, power management, and utility operations.
public DcMotorEnhanced(DcMotor motor)
setPosAndWait(int targetPosition, OpModeBase opmode)- Moves to a position at default speed, waits until there. Moves at the preset default speed
- Example:
setPosAndWait(500, this)The reason you add thethishas to do with allowing the motor to control the control loop of the opMode.
setPosAndWait(int targetPosition, double speed, OpModeBase opmode)- Moves to a position at given speed, waits until there.
- Example:
setPosAndWait(500,0.7,this)// Make sure to include this
setPosition(int targetPosition)- Go to position at default speed (doesn’t wait).
setPosition(int targetPosition, double speed)- Go to position at specified speed.
setDefaultSpeed(double speed),getDefaultSpeed()setPower(double power),getPower(). Note, this will override the motor mode toDcMotor.RunMode.RUN_WITHOUT_ENCODER. It will be set back when calling an encoder-based action like setPosition()
reset()
Resets encoder to 0. Will stop the motor to reset.isAtTarget()
Returns true if withinConstants.ENCODER_TOLERANCEof target.getCurrentPosition()Return the encoder positionisBusy()Returns true if moving
-
setMode(DcMotor.RunMode mode),getMode()- Options:
RUN_WITHOUT_ENCODERRUN_USING_ENCODERRUN_TO_POSITIONSTOP_AND_RESET_ENCODER
-
setZeroPowerBehavior(DcMotor.ZeroPowerBehavior behavior),getZeroPowerBehavior()Sets how the motor acts when no power is appliedBRAKEorFLOAT -
setDirection(DcMotorSimple.Direction direction),getDirection()FORWARDorREVERSE
getBaseMotor()
Returns the raw underlyingDcMotor. It is very rate you will need to access this
Purpose:
Driver for the goBILDA® Pinpoint Odometry Computer.
Handles communication, configuration, and reading robot pose/velocity.
- Constructed by FTC SDK’s hardwareMap (
hardwareMap.get(GoBildaPinpointDriver.class,"odo")).
update()- Reads all odometry data (should be called each loop).
update(ReadData data)- Reads only the heading (for performance).
setOffsets(double xOffset, double yOffset)- Set pod offsets in mm (deprecated: see overload with
DistanceUnit).
- Set pod offsets in mm (deprecated: see overload with
setOffsets(double xOffset, double yOffset, DistanceUnit distanceUnit)setEncoderDirections(EncoderDirection x, EncoderDirection y)setEncoderResolution(GoBildaOdometryPods podType)setEncoderResolution(double ticks_per_mm)setEncoderResolution(double ticks_per_unit, DistanceUnit distanceUnit)
recalibrateIMU()- Zero the IMU (robot must be still).
resetPosAndIMU()- Zero position and IMU.
setPosition(Pose2D pos)setPosX(double posX, DistanceUnit unit)setPosY(double posY, DistanceUnit unit)setHeading(double heading, AngleUnit unit)getPosition()getAngle(),getAngle(AngleUnit),getAngle(UnnormalizedAngleUnit)getX(),getY(),getAngle()
getDeviceID(),getDeviceVersion()getDeviceStatus()getLoopTime(),getFrequency()getEncoderX(),getEncoderY()getYawScalar()
getVelX(),getVelX(DistanceUnit)getVelY(),getVelY(DistanceUnit)getHeadingVelocity(),getHeadingVelocity(UnnormalizedAngleUnit)getVelocity()
getXOffset(DistanceUnit),getYOffset(DistanceUnit)getPinpoint()
- Create an OpMode (autonomous: extend
AutoBase; teleop: extendTeleOpBase) - Override the required abstract methods (
runSequence,runInit,runLoop, etc.) - Call movement and hardware methods to control your robot.
- Tune constants in
Constants.javaas needed (dashboard compatible). - Use odometry and drive utilities for accurate and efficient robot control.
- Each class and method is documented with purpose, usage, and scenarios.
- For detailed code reference, see the .java files.
- For FTC SDK integration, see FTC documentation.
- If you can't find info about something or you need a quick answer, use GitHub Copilot with this codebase attached for info.
- If nothing else works, ask Josh.