/** * 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 returns the number of motors in the drive train. * * @return number of motors. */ public int getNumMotors() { final String funcName = "getNumMotors"; if (debugEnabled) { dbgTrace.traceEnter(funcName, TrcDbgTrace.TraceLevel.API); dbgTrace.traceExit(funcName, TrcDbgTrace.TraceLevel.API, "=%d", numMotors); } return numMotors; } // getNumMotors
/** * This method sets the maximum output value of the motor. * * @param maxOutput specifies the maximum output value. */ public void setMaxOutput(double maxOutput) { final String funcName = "setMaxOutput"; if (debugEnabled) { dbgTrace.traceEnter(funcName, TrcDbgTrace.TraceLevel.API, "maxOutput=%f", maxOutput); dbgTrace.traceExit(funcName, TrcDbgTrace.TraceLevel.API); } this.maxOutput = maxOutput; } // setMaxOutput
/** * This method sets the sensitivity for the drive() method. * * @param sensitivity specifies the sensitivity value. */ public void setSensitivity(double sensitivity) { final String funcName = "setSensitivity"; if (debugEnabled) { dbgTrace.traceEnter(funcName, TrcDbgTrace.TraceLevel.API, "sensitivity=%f", sensitivity); dbgTrace.traceExit(funcName, TrcDbgTrace.TraceLevel.API); } this.sensitivity = sensitivity; } // setSensitivity
/** * 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 stops all the motors. */ public void stopMotor() { final String funcName = "stopMotor"; if (debugEnabled) { dbgTrace.traceEnter(funcName, TrcDbgTrace.TraceLevel.API); dbgTrace.traceExit(funcName, TrcDbgTrace.TraceLevel.API); } if (frontLeftMotor != null) frontLeftMotor.setPower(0.0); if (frontRightMotor != null) frontRightMotor.setPower(0.0); if (rearLeftMotor != null) rearLeftMotor.setPower(0.0); if (rearRightMotor != null) rearRightMotor.setPower(0.0); } // stopMotor
/** * 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
/** * This method inverts direction of a given motor in the drive train. * * @param motorType specifies the motor in the drive train. * @param isInverted specifies true if inverting motor direction. */ public void setInvertedMotor(MotorType motorType, boolean isInverted) { final String funcName = "setInvertedMotor"; if (debugEnabled) { dbgTrace.traceEnter( funcName, TrcDbgTrace.TraceLevel.API, "type=%s,inverted=%s", motorType.toString(), Boolean.toString(isInverted)); dbgTrace.traceExit(funcName, TrcDbgTrace.TraceLevel.API); } switch (motorType.value) { case MotorType.kFrontLeft_val: if (frontLeftMotor != null) { frontLeftMotor.setInverted(isInverted); } break; case MotorType.kFrontRight_val: if (frontRightMotor != null) { frontRightMotor.setInverted(isInverted); } break; case MotorType.kRearLeft_val: if (rearLeftMotor != null) { rearLeftMotor.setInverted(isInverted); } break; case MotorType.kRearRight_val: if (rearRightMotor != null) { rearRightMotor.setInverted(isInverted); } break; } } // setInvertedMotor
/** * This method drives the motors with the given magnitude and curve values. * * @param magnitude specifies the magnitude value. * @param curve specifies the curve value. * @param inverted specifies true to invert control (i.e. robot front becomes robot back). */ public void drive(double magnitude, double curve, boolean inverted) { final String funcName = "drive"; double leftOutput; double rightOutput; if (debugEnabled) { dbgTrace.traceEnter( funcName, TrcDbgTrace.TraceLevel.API, "mag=%f,curve=%f,inverted=%s", magnitude, curve, Boolean.toString(inverted)); dbgTrace.traceExit(funcName, TrcDbgTrace.TraceLevel.API); } if (curve < 0.0) { double value = Math.log(-curve); double ratio = (value - sensitivity) / (value + sensitivity); if (ratio == 0.0) { ratio = 0.0000000001; } leftOutput = magnitude / ratio; rightOutput = magnitude; } else if (curve > 0.0) { double value = Math.log(curve); double ratio = (value - sensitivity) / (value + sensitivity); if (ratio == 0.0) { ratio = 0.0000000001; } leftOutput = magnitude; rightOutput = magnitude / ratio; } else { leftOutput = magnitude; rightOutput = magnitude; } tankDrive(leftOutput, rightOutput, inverted); } // drive