this is all our code for a teleop that is controlled by players. make another code called autonomus.java or something and make it use a camera with image recognition to detect game pieces. make sure it is a trainable model like yolov8 and tell me how to do it as well. make it completely autonomus since in this challenge, players cant control. here is the teleop code: package org.firstinspires.ftc.teamcode;

import com.qualcomm.robotcore.eventloop.opmode.Disabled;
import com.qualcomm.robotcore.eventloop.opmode.OpMode;
import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
import com.qualcomm.robotcore.hardware.DcMotor;
import com.qualcomm.robotcore.util.ElapsedTime;
import com.qualcomm.robotcore.util.Range;

@TeleOp(name="Mecanum Drive", group="Iterative OpMode")
public class TeleOpMode extends OpMode
{
    // Declare OpMode members.
    private ElapsedTime runtime = new ElapsedTime();
    private DcMotor frontLeftDrive = null;
    private DcMotor frontRightDrive = null;
    private DcMotor backLeftDrive = null;
    private DcMotor backRightDrive = null;
    private DcMotor armMotor = null;

    private boolean precisionMode = false;
    private double speedMultiplier = 1.0;
    private double armPower = 0;

    /*
     * Code to run ONCE when the driver hits INIT
     */
    @Override
    public void init() {
        telemetry.addData("Status", "Initialized");

        // Initialize the hardware variables. Note that the strings used here as parameters
        // to 'get' must correspond to the names assigned during the robot configuration
        // step (using the FTC Robot Controller app on the phone).
        frontLeftDrive = hardwareMap.get(DcMotor.class, "front_left_drive");
        frontRightDrive = hardwareMap.get(DcMotor.class, "front_right_drive");
        backLeftDrive = hardwareMap.get(DcMotor.class, "back_left_drive");
        backRightDrive = hardwareMap.get(DcMotor.class, "back_right_drive");
        armMotor = hardwareMap.get(DcMotor.class, "joint_one");

        // To drive forward, most robots need the motor on one side to be reversed, because the axles point in opposite directions.
        // Pushing the left stick forward MUST make robot go forward. So adjust these two lines based on your first test drive.
        // Note: The settings here assume direct drive on left and right wheels.  Gear Reduction or 90 Deg drives may require direction flips
        frontLeftDrive.setDirection(DcMotor.Direction.REVERSE);
        frontRightDrive.setDirection(DcMotor.Direction.FORWARD);
        backLeftDrive.setDirection(DcMotor.Direction.REVERSE);
        backRightDrive.setDirection(DcMotor.Direction.FORWARD);
        armMotor.setDirection(DcMotor.Direction.FORWARD); // REV Robotics Core Hex Motor

        // Tell the driver that initialization is complete.
        telemetry.addData("Status", "Initialized");
    }

    /*
     * Code to run REPEATEDLY after the driver hits INIT, but before they hit START
     */
    @Override
    public void init_loop() {
    }

    /*
     * Code run ONCE when the driver hits START
     */
    @Override
    public void start() {
        runtime.reset();
    }

    /*
     * Code to run REPEATEDLY after the driver hits START but before they hit STOP
     */
    @Override
    public void loop() {
        // Setup a variable for each drive wheel to save power level for telemetry
        double frontLeftPower;
        double frontRightPower;
        double backLeftPower;
        double backRightPower;

        // Check if precision mode is enabled
        if(gamepad1.left_bumper){
            speedMultiplier = 0.5;
        }
        else{
            speedMultiplier = 1;
        }

        // Calculate the mecanum drive values
        double drive = -gamepad1.left_stick_y * speedMultiplier;
        double strafe = gamepad1.left_stick_x * 0.5 * speedMultiplier; // Reduce strafing speed to half
        double turn = gamepad1.right_stick_x * speedMultiplier;
        if (Math.abs(gamepad1.right_stick_x) < 0.1) {
            turn = 0;
        }

        // Calculate the motor powers
        frontLeftPower = drive + strafe + turn;
        frontRightPower = drive - strafe - turn;
        backLeftPower = drive - strafe + turn;
        backRightPower = drive + strafe - turn;

        // Clip the motor powers to ensure they are within the valid range
        frontLeftPower = Range.clip(frontLeftPower, -1.0, 1.0);
        frontRightPower = Range.clip(frontRightPower, -1.0, 1.0);
        backLeftPower = Range.clip(backLeftPower, -1.0, 1.0);
        backRightPower= Range.clip(backRightPower, -1.0, 1.0);

// Send calculated power to wheels
        frontLeftDrive.setPower(frontLeftPower);
        frontRightDrive.setPower(frontRightPower);
        backLeftDrive.setPower(backLeftPower);
        backRightDrive.setPower(backRightPower);

// Control the arm using the D-pad up and down buttons
        if (gamepad1.dpad_up) {
            armPower = 0.5;
        } else if (gamepad1.dpad_down) {
            armPower = -0.5;
        } else {
            armPower = 0;
        }

// Adjust the arm power to account for the 20:1 gear ratio
        armPower *= 2; // Adjusted to 0.5 to increase arm movement

// Send calculated power to arm motor
        armMotor.setPower(armPower);

// Debugging for arm
        if (gamepad1.dpad_up) {
            telemetry.addData("Arm Power", "Up");
        } else if (gamepad1.dpad_down) {
            telemetry.addData("Arm", "Down");
        } else {
            telemetry.addData("Arm", "Neutral");
        }

// Show the game time and wheel power.
        telemetry.addData("Status", "Run Time: " + runtime.toString());
        telemetry.addData("Motors", "frontLeft (%.2f), frontRight (%.2f), backLeft (%.2f), backRight (%.2f)", frontLeftPower, frontRightPower, backLeftPower, backRightPower);
        telemetry.addData("Arm Power", armPower);
    }

    /*
     * Code to run ONCE after the driver hits STOP
     */
    @Override
    public void stop() {
    }
}