Computer Science
Gilmour AcademyLancerTech
  • Our Curriculum and Department
  • Intro to Programming
    • 1: Parts of a Computer
    • 2: Parts of Python
    • 3: DRY Turtle
    • 4: Turtle Design App
    • Wordle with Turtles
    • 5: Interactive Turtles
    • OLD 5: Replit, GitHub, and repositories (Oh my!)
    • 6: Raspberry Pi / GoPiGo
    • 7: Kivy
  • Intro to Web Design
    • 1: Internet?
    • 2: Websites?
    • 3: Bootstrap Template
    • 4: Graphics and Branding
    • 5: Collaboration
    • 6: Advanced Editing
    • Publish Static HTML
  • AP Computer Science
    • 1: Logic & Instances
    • 2: How Java Works
    • 3: Data Types & Flow
    • 4: Strings
    • 5: Objects & References
    • 6: Inheritance & Algorithms
    • 7: Data Structures
    • 8: Sorting
    • 9: Review
    • Data Science
  • Web App Dev
    • 1: Core Concepts
    • 2: MVT Pattern
    • 3: Hello Flask
    • 4: Install Flaskinni
    • 5: Tour Flaskinni
    • 6: Visualize Your App
    • 7: Theme & Blueprint
    • 8: Standup Your DB
    • 9: Advanced Topics
    • 10: Deployment
  • 2D Game Design
    • Class Overview
    • Gamemaker Studio 2 and Github Setup
    • Game 1: Bouncing Ball
    • Turning in your games
    • Game 2: Maze
    • Game 3: Ping Pong
    • Game 4: Breakout
    • Game 5: Tank Battle
    • Game 6 Highlights
    • DO NOT DO:
    • Game 7: Final Project
    • Publish to Opera
    • FAQ
  • 3D Game Design
    • 1: Class Overview
    • 2: Installation
    • 3: Exploring the Unity UI
    • Game 1: Rolling Ball
    • Game 2: Tanks
    • Game 3: Third Person Platformer
    • Game 4: Final project
    • FAQs
    • OLD: Distance Learning Setup
    • OLD: GIT
  • 3D Modeling & Fabrication
    • Installation
    • Fusion 360 Interface and Sketch Modeling
    • Primitive Modeling
    • Patterns
    • Appearances and Rendering
    • Building Community Gallery Page 2023
    • Parametric Modeling
    • 3D Printing Concerns
    • Assemblies and Mechanical Design
    • Laser Cutting
    • Sculpt Tools
    • Milling Concerns
  • Robotics 7
    • Software Installation
    • Python basics (trinket.io)
    • Python Turtle
    • Programming for the Ev3
    • Setting up for clarity
  • Robotics 8
    • Replit
    • Python review
    • Kivy Basics
    • Calculator
  • Competitive Robotics
    • Hardware Team
      • CAD Examples
      • Elevators
    • Software Team
      • Command Pattern
      • Example Command
      • Subsystem
      • Running Your Code
      • Under the Hood
      • RoadRunner
      • Vision Processing
  • Archives
    • Adiletta Archives
      • Old Web
        • Ex: WordPress CMS
      • ItP
        • OLD: Parts of Python (old -- Mr. A)
        • OLD: 5: Raspberry Pi
        • OLD: 6: Deploying Code
        • OLD 7: Nav Algorithm
    • Vanek Archives
      • OLD Robotics 8
        • OLD: End of Class Project
      • OLD Competitive Robotics
        • Untitled
        • Webots Videos
      • OLD Robotics 7
        • Trinket Introduction
        • Lists: x/y position
        • Functions: Math program
        • Lists: Grocery List
        • Study Guide Program
        • Tic Tac Toe Game
        • Dice Roller Program
        • Visualization
        • Dice Roller + Visualization
        • OpenSCAD: Installation
        • OpenSCAD: Command Sheet and Intro
        • OpenSCAD: Difference
        • OpenSCAD: Variables
        • OpenSCAD: Union
        • OpenSCAD: For Loops
        • OpenSCAD: Final Project
      • OLD Art I - Blender Sculpting
        • Class Overview
        • Installation
        • Lesson 1 - Tools
        • Lesson 2 - Detail
        • Lesson 3 - Base Mesh: Metaballs
        • Lesson 4: Converting metaballs and adding detail
        • Lesson 5: Masking, Hiding, and Working with Multiple Objects
        • Lesson 6: Joining Objects & Basing
        • Lesson 7: Sculpture Painting
        • Student Gallery: Animal Sculpts
        • Lesson 8: 3D Compositon
        • Lesson 9: The Project - Putting it all together
        • Lesson 10: Developing the image further
        • Lesson 11: Layout the base metaball mesh.
        • Lesson 12: Final Detail
        • Lesson 13: Basing and Painting
        • Final Project Gallery
      • OLD Fab
        • OLD Building Community Project Gallery
        • Copy of Building Community Project Gallery
        • old Building Community Project Gallery
      • OLD: Turtle Design App
      • OLD Arduino Robotics 8
        • Arduino Basic Commands Cheat Sheet
        • Logging into Tinkercad
        • Arduino, Circuits, LEDs and Resistors
        • Functions and Variables
        • Serial Monitor
        • Buttons and Interrupts
        • Traffic Light Project
        • Potentiometers + Servos
        • Piezo Buzzer and Tone();
        • Sequencer Project
        • Arrays and for loops
        • Extra Loop Practice
        • Refining the Sequencer
        • Servos
        • Ultrasonic Sensors
        • Final Project
Powered by GitBook
On this page
  • What are subsystems in FTCLib?
  • Why do we use this Subsystem design?
  • Example Subsystem

Was this helpful?

Export as PDF
  1. Competitive Robotics
  2. Software Team

Subsystem

The composition of hardware components and their basic helper functions

What are subsystems in FTCLib?

An FTCLib Subsystem is like a part of your robot that controls specific tasks, such as driving, lifting an arm, or shooting a game element. Each subsystem has its own job and knows how to control the motors, sensors, or other components related to that job. By breaking the robot into subsystems, your code becomes easier to manage and update because each part is responsible for its own actions. Think of it like different departments in a company—each one has a clear purpose, making the whole robot work smoothly together.

Why do we use this Subsystem design?

The advantage of using subsystems in FTCLib is that it allows for smooth control of multiple parts of your robot at once. Organizing your code this way allows you to run several subsystems without everything happening in one big block. This means one thread can manage multiple subsystems simultaneously without commands blocking each other. For example, the robot can move and operate its arm, and if a new command interrupts a current action—like stopping the drive to shoot a game element—it can smoothly switch tasks without delays or confusion.

Example Subsystem

package org.firstinspires.ftc.teamcode.subsystems;

// EXAMPLE SUBSYSTEM
public class Arm extends SubsystemBase {
    // SUBSYSTEM ASSETS
    private final MyRobot robot;
    private final Servo wristServo, openServo, rollServo;
    public final MotorEx motor;
    // STATE VARIABLES
    private double wristAng = HardwareNames.WRIST_MIN;
    private double rollPos = HardwareNames.ROLL_MAX;
    private boolean isOpen = false;
    private int offset = 0;

    public Arm(MyRobot robot) {
        this.robot = robot;
        HardwareMap hardwareMap = robot.opMode.hardwareMap;

        // shoulder motor
        this.motor = new MotorEx(hardwareMap, HardwareNames.ARM_MOTOR_NAME);
        motor.setRunMode(Motor.RunMode.PositionControl);
        motor.setInverted(true);
        motor.setPositionCoefficient(HardwareNames.ARM_MOTOR_kP);
        motor.setPositionTolerance(HardwareNames.ARM_MOTOR_TOLERANCE);

        // servos
        wristServo = hardwareMap.get(Servo.class, HardwareNames.WRIST_SERVO_NAME);
        openServo = hardwareMap.get(Servo.class, HardwareNames.OPEN_SERVO_NAME);
        rollServo = hardwareMap.get(Servo.class, HardwareNames.ROLL_SERVO_NAME);
        wristServo.setPosition(wristAng);
        openServo.setPosition(HardwareNames.CLAW_CLOSED_POS);
        rollServo.setPosition(rollPos);
    }

    // -- EXAMPLE SERVO COMMANDS --
    public void travelMode() {
        closeClaw();
        wristServo.setPosition(0);
        wristAng = 0;
    }
    public void wristUp() {
        wristAng -= HardwareNames.WRIST_INC;
        wristAng = Range.clip(wristAng, HardwareNames.WRIST_MIN, HardwareNames.WRIST_MAX);
        wristServo.setPosition(wristAng);
    }
    public void wristDown() {
        wristAng += HardwareNames.WRIST_INC;
        wristAng = Range.clip(wristAng, HardwareNames.WRIST_MIN, HardwareNames.WRIST_MAX);
        wristServo.setPosition(wristAng);
    }
    public void openClaw() {
        openServo.setPosition(HardwareNames.CLAW_OPEN_POS);
        isOpen = true;
    }
    public void closeClaw() {
        openServo.setPosition(HardwareNames.CLAW_CLOSED_POS);
        isOpen = false;
    }
    public void toggleOpen() {
        if(isOpen) {
            closeClaw();
        } else {
            openClaw();
        }
    }
    public void toggleRoll() {
        if(rollServo.getPosition() >= .5){
            rollServo.setPosition(HardwareNames.ROLL_MIN);
            rollPos = HardwareNames.ROLL_MIN;
        } else{
            rollServo.setPosition(HardwareNames.ROLL_MAX);
            rollPos = HardwareNames.ROLL_MAX;
        }
    }

    @NonNull
    @Override
    public String toString() {
        return String.format(Locale.ENGLISH, "OPR: (%f, %f, %f)",
                openServo.getPosition(), wristServo.getPosition(), rollServo.getPosition());
    }
}

Hardware and Setup:

The Arm subsystem in our example demonstrates essential aspects of subsystem creation:

  1. Hardware References: Declares member variables like motor, wristServo, etc., linking them to hardware names from a centralized place for these "magic strings," such as HardwareNames.

  2. Motor Configuration: Sets up the motor for precise position control using MotorEx, defining parameters like PID coefficients and tolerances.

  3. Servo Initialization: Retrieves servo objects from the hardwareMap and sets their initial positions.

Helpful Methods:

Subsystems often include convenience methods to control hardware directly. The Arm class provides examples:

  • travelMode(): Sets the arm for driving by closing the claw, adjusting the wrist, and storing the new wrist position.

  • wristUp()/wristDown(): Increment/decrement the wrist servo position within set limits.

  • openClaw()/closeClaw(): Manipulate the claw servo based on an isOpen boolean flag.

  • toggleOpen()/toggleRoll(): Implement button-pressable actions using conditional logic.

State Management:

Subsystems can maintain internal state using variables like isOpen for the claw. The toString() method provides a human-readable snapshot of the subsystem's current state (servo positions in this case).

Where do state variables go?

There are state variables like wristAng and isOpen in this subsystem. Does every subsystem get unique state variables? Should we consolidate them into the MyRobotfile? These are organizational guidelines that are flexible and will need to be discussed so all programmers know how things ought to be organized.

Beyond Commands:

Remember, not every action needs a dedicated Command. Servos like the wrist can be adjusted directly using methods like wristUp(). They're instantaneous and aren't a threat to block off other commands. So here's how we can bind these to a button (more details in Running Your Code).

    Button dPadUpP2 = new GamepadButton(player2, GamepadKeys.Button.DPAD_UP);
    dPadUpP2.whileHeld(new InstantCommand(() -> {
        arm.wristUp();
    }));

Next Steps:

While this explanation covers the basics of subsystems, exploring the provided Robot OpMode will reveal how these subsystems are integrated and controlled within your robot's overall behavior. Remember, effectively utilizing subsystems is vital in writing well-structured and maintainable robot code in FTCLib.

PreviousExample CommandNextRunning Your Code

Last updated 7 months ago

Was this helpful?