/** * This method implements mecanum drive where x controls how fast the robot will go in the x * direction, and y controls how fast the robot will go in the y direction. Rotation controls how * fast the robot rotates and gyroAngle specifies the heading the robot should maintain. * * @param x specifies the x power. * @param y specifies the y power. * @param rotation specifies the rotating power. * @param inverted specifies true to invert control (i.e. robot front becomes robot back). * @param gyroAngle specifies the gyro angle to maintain. */ public void mecanumDrive_Cartesian( double x, double y, double rotation, boolean inverted, double gyroAngle) { final String funcName = "mecanumDrive_Cartesian"; if (debugEnabled) { dbgTrace.traceEnter( funcName, TrcDbgTrace.TraceLevel.API, "x=%f,y=%f,rot=%f,inverted=%s,angle=%f", x, y, rotation, Boolean.toString(inverted), gyroAngle); dbgTrace.traceExit(funcName, TrcDbgTrace.TraceLevel.API); } if (numMotors != MAX_NUM_MOTORS) { throw new IllegalArgumentException("Mecanum drive requires 4 motors"); } x = TrcUtil.limit(x); y = TrcUtil.limit(y); rotation = TrcUtil.limit(rotation); if (inverted) { x = -x; y = -y; } double cosA = Math.cos(Math.toRadians(gyroAngle)); double sinA = Math.sin(Math.toRadians(gyroAngle)); x = x * cosA - y * sinA; y = x * sinA + y * cosA; double wheelSpeeds[] = new double[MAX_NUM_MOTORS]; wheelSpeeds[MotorType.kFrontLeft_val] = x + y + rotation; wheelSpeeds[MotorType.kFrontRight_val] = -x + y - rotation; wheelSpeeds[MotorType.kRearLeft_val] = -x + y + rotation; wheelSpeeds[MotorType.kRearRight_val] = x + y - rotation; normalize(wheelSpeeds); if (frontLeftMotor != null) { frontLeftMotor.setPower(wheelSpeeds[MotorType.kFrontLeft_val]); } if (frontRightMotor != null) { frontRightMotor.setPower(wheelSpeeds[MotorType.kFrontRight_val]); } if (rearLeftMotor != null) { rearLeftMotor.setPower(wheelSpeeds[MotorType.kRearLeft_val]); } if (rearRightMotor != null) { rearRightMotor.setPower(wheelSpeeds[MotorType.kRearRight_val]); } } // mecanumDrive_Cartesian
/** * This method implements arcade drive where drivePower controls how fast the robot goes in the * y-axis and turnPower controls how fast it will turn. * * @param drivePower specifies the drive power value. * @param turnPower specifies the turn power value. * @param inverted specifies true to invert control (i.e. robot front becomes robot back). */ public void arcadeDrive(double drivePower, double turnPower, boolean inverted) { final String funcName = "arcadeDrive"; double leftPower; double rightPower; if (debugEnabled) { dbgTrace.traceEnter( funcName, TrcDbgTrace.TraceLevel.API, "drivePower=%f,turnPower=%f,inverted=%s", drivePower, turnPower, Boolean.toString(inverted)); dbgTrace.traceExit(funcName, TrcDbgTrace.TraceLevel.API); } drivePower = TrcUtil.limit(drivePower); turnPower = TrcUtil.limit(turnPower); if (drivePower + turnPower > MOTOR_MAX_VALUE) { // // Forward right: // left = drive + turn - (drive + turn - MOTOR_MAX_VALUE) // right = drive - turn - (drive + turn - MOTOR_MAX_VALUE) // leftPower = MOTOR_MAX_VALUE; rightPower = -2 * turnPower + MOTOR_MAX_VALUE; } else if (drivePower - turnPower > MOTOR_MAX_VALUE) { // // Forward left: // left = drive + turn - (drive - turn - MOTOR_MAX_VALUE) // right = drive - turn - (drive - turn - MOTOR_MAX_VALUE) // leftPower = 2 * turnPower + MOTOR_MAX_VALUE; rightPower = MOTOR_MAX_VALUE; } else if (drivePower + turnPower < MOTOR_MIN_VALUE) { // // Backward left: // left = drive + turn - (drive + turn - MOTOR_MIN_VALUE) // right = drive - turn - (drive + turn - MOTOR_MIN_VALUE) // leftPower = MOTOR_MIN_VALUE; rightPower = -2 * turnPower + MOTOR_MIN_VALUE; } else if (drivePower - turnPower < MOTOR_MIN_VALUE) { // // Backward right: // left = drive + turn - (drive - turn - MOTOR_MIN_VALUE) // right = drive - turn - (drive - turn - MOTOR_MIN_VALUE) // leftPower = 2 * turnPower + MOTOR_MIN_VALUE; rightPower = MOTOR_MIN_VALUE; } else { leftPower = drivePower + turnPower; rightPower = drivePower - turnPower; } tankDrive(leftPower, rightPower, inverted); } // arcadeDrive
/** * This method implements mecanum drive where magnitude controls how fast the robot will go in the * given direction and how fast it will robote. * * @param magnitude specifies the magnitude combining x and y axes. * @param direction specifies the direction in degrees. * @param rotation specifies the rotation power. * @param inverted specifies true to invert control (i.e. robot front becomes robot back). */ public void mecanumDrive_Polar( double magnitude, double direction, double rotation, boolean inverted) { final String funcName = "mecanumDrive_Polar"; if (debugEnabled) { dbgTrace.traceEnter( funcName, TrcDbgTrace.TraceLevel.API, "mag=%f,dir=%f,rot=%f,inverted=%s", magnitude, direction, rotation, Boolean.toString(inverted)); dbgTrace.traceExit(funcName, TrcDbgTrace.TraceLevel.API); } if (numMotors != MAX_NUM_MOTORS) { throw new IllegalArgumentException("Mecanum drive requires 4 motors"); } magnitude = TrcUtil.limit(magnitude) * Math.sqrt(2.0); if (inverted) { direction += 180.0; direction %= 360.0; } double dirInRad = Math.toRadians(direction + 45.0); double cosD = Math.cos(dirInRad); double sinD = Math.sin(dirInRad); double wheelSpeeds[] = new double[MAX_NUM_MOTORS]; wheelSpeeds[MotorType.kFrontLeft_val] = (sinD * magnitude + rotation); wheelSpeeds[MotorType.kFrontRight_val] = (cosD * magnitude - rotation); wheelSpeeds[MotorType.kRearLeft_val] = (cosD * magnitude + rotation); wheelSpeeds[MotorType.kRearRight_val] = (sinD * magnitude - rotation); normalize(wheelSpeeds); if (frontLeftMotor != null) { frontLeftMotor.setPower(wheelSpeeds[MotorType.kFrontLeft_val]); } if (frontRightMotor != null) { frontRightMotor.setPower(wheelSpeeds[MotorType.kFrontRight_val]); } if (rearLeftMotor != null) { rearLeftMotor.setPower(wheelSpeeds[MotorType.kRearLeft_val]); } if (rearRightMotor != null) { rearRightMotor.setPower(wheelSpeeds[MotorType.kRearRight_val]); } } // mecanumDrive_Polar
/** * This method implements tank drive where leftPower controls the left motors and right power * controls the right motors. * * @param leftPower specifies left power value. * @param rightPower specifies right power value. * @param inverted specifies true to invert control (i.e. robot front becomes robot back). */ public void tankDrive(double leftPower, double rightPower, boolean inverted) { final String funcName = "tankDrive"; if (debugEnabled) { dbgTrace.traceEnter( funcName, TrcDbgTrace.TraceLevel.API, "leftPower=%f,rightPower=%f,inverted=%s", leftPower, rightPower, Boolean.toString(inverted)); dbgTrace.traceExit(funcName, TrcDbgTrace.TraceLevel.API); } leftPower = TrcUtil.limit(leftPower); rightPower = TrcUtil.limit(rightPower); if (inverted) { double swap = leftPower; leftPower = -rightPower; rightPower = -swap; } if (frontLeftMotor != null) { frontLeftMotor.setPower(leftPower); } if (frontRightMotor != null) { frontRightMotor.setPower(rightPower); } if (rearLeftMotor != null) { rearLeftMotor.setPower(leftPower); } if (rearRightMotor != null) { rearRightMotor.setPower(rightPower); } } // tankDrive