How to turn robot using arcade drive

Hello, my team and I are rookies this year, so we don’t have a lot of experience. I have the code for moving the robot but I don’t know how to make the robot turn. If anyone could help me with my problem I would really appreciate it.
Thank you - Team 6480

More detail would definitely help.

Assuming that: you are using the built in arcade method, have a skid-steer (tank) drive system with two gearboxes, one driving the left wheels and the other driving the right, and you have set up the two axes of the same joystick to the arcade method, all you should have to do is move the joystick left or right.

Put the robot on blocks. When you try to go forward, do all the wheels turn the same direction? If not, you need to invert the motors on the side going backwards.
Then, attempt to turn (move joystick to the right or left), do the wheels spin opposite directions?

If the wheels spin opposite directions but the robot does not turn, you may have made your robot too long to be an effective skid-steer. If you have 6 or 8 wheels, make sure that the center wheels are lower than the corner wheels (should be a slight rocking motion). If you only have four, your best option short of re-building the chassis is to get some Omni wheels (same diameter as you have now) and swap out at least two (one on each side), possibly all four.

Edit: Again, please provide details (e.g. code and a photo of your robot and what is actually happening now) for more specific help.

this is our code :

package org.usfirst.frc.team6480.robot;

import edu.wpi.first.wpilibj.IterativeRobot;
import edu.wpi.first.wpilibj.Jaguar;
import edu.wpi.first.wpilibj.Joystick;
import edu.wpi.first.wpilibj.Victor;
import edu.wpi.first.wpilibj.smartdashboard.SendableChooser;

/**

  • The VM is configured to automatically run this class, and to call the

  • functions corresponding to each mode, as described in the IterativeRobot

  • documentation. If you change the name of this class or the package after

  • creating this project, you must also update the manifest file in the resource

  • directory.
    */
    public class Robot extends IterativeRobot {
    final String defaultAuto = “Default”;
    final String customAuto = “My Auto”;
    String autoSelected;
    SendableChooser<String> chooser = new SendableChooser<>();

    Jaguar lf = new Jaguar(0);
    Victor lb = new Victor(1);
    Jaguar rf = new Jaguar(2);
    Victor rb = new Victor(3);
    Joystick stick = new Joystick(0);
    long rate = 5000;
    long time;

    /**

    • This function is run when the robot is first started up and should be
    • used for any initialization code.
      */
      @Override
      public void robotInit() {
      rf.setInverted(true);
      rb.setInverted(true);
      }

    /**

    • This autonomous (along with the chooser code above) shows how to select
    • between different autonomous modes using the dashboard. The sendable
    • chooser code works with the Java SmartDashboard. If you prefer the
    • LabVIEW Dashboard, remove all of the chooser code and uncomment the
    • getString line to get the auto name from the text box below the Gyro
    • You can add additional auto modes by adding additional comparisons to the
    • switch structure below with additional strings. If using the
    • SendableChooser make sure to add them to the chooser code above as well.
      */
      @Override
      public void autonomousInit() {
      time = System.currentTimeMillis()+rate;
      }

    /**

    • This function is called periodically during autonomous
      */
      @Override
      public void autonomousPeriodic() {
      if(System.currentTimeMillis()<time){
      lf.set(1.0);
      lb.set(1.0);
      rf.set(1.0);
      rb.set(1.0);
      }
      }

    /**

    • This function is called periodically during operator control
      */
      @Override
      public void teleopPeriodic() {

    lf.set(stick.getZ());
    lb.set(stick.getY());
    rf.set(stick.getZ());
    rb.set(stick.getY());

    }

    /**

    • This function is called periodically during test mode
      */
      @Override
      public void testPeriodic() {
      }

You guys are going to need to show us what code you have written and what the robot does when it runs for any useful help, otherwise everyone who tries to help you will be basing their advice on guesses.

Not only does it help us solve the exact problem you’re looking for, others may detect other problems you could run into.

Great username btw.

FIRST provided a lot of sample code. In particular, I took the TankDrive sample code, deleted one line and changed two lines and it became an ArcadeDrive sample. I am assuming you have all the motors going the correct directions. If not, you may need to add a line to invert a motor.


package org.usfirst.frc.team492.robot;

import edu.wpi.first.wpilibj.SampleRobot;
import edu.wpi.first.wpilibj.RobotDrive;
import edu.wpi.first.wpilibj.Joystick;
import edu.wpi.first.wpilibj.Timer;

/**
 * This is a demo program showing the use of the RobotDrive class, specifically
 * it contains the code necessary to operate a robot with tank drive.
 *
 * The VM is configured to automatically run this class, and to call the
 * functions corresponding to each mode, as described in the SampleRobot
 * documentation. If you change the name of this class or the package after
 * creating this project, you must also update the manifest file in the resource
 * directory.
 *
 * WARNING: While it may look like a good choice to use for your code if you're
 * inexperienced, don't. Unless you know what you are doing, complex code will
 * be much more difficult under this system. Use IterativeRobot or Command-Based
 * instead if you're new.
 */
public class Robot extends SampleRobot {
	RobotDrive myRobot = new RobotDrive(0, 1); // class that handles basic drive
												// operations
	Joystick driveStick = new Joystick(0); // set to ID 1 in DriverStation

	public Robot() {
		myRobot.setExpiration(0.1);
	}

	/**
	 * Runs the motors with tank steering.
	 */
	@Override
	public void operatorControl() {
		myRobot.setSafetyEnabled(true);
		while (isOperatorControl() && isEnabled()) {
			myRobot.arcadeDrive(driveStick);
			Timer.delay(0.005); // wait for a motor update time
		}
	}
}

If you guys have an xbox controller I find that best controls that most drivers are comfortable with is driving forward and backwards with the left stick on the xbox and left and right with the the right stick. Its very easy to control

Code :

myRobot.arcadeDrive(driveStick.getRawAxis(1), driveStick.getRawAxis(4))

This is great advice. Also, when you pass double values to arcadeDrive and not just the stick, you can start to manipulate the numbers to customize your driving. For instance, if you wanted to add sensitivity to your driving ability, you could multiply all your axis values by a sensitivity constant (like .75) to cut down on speed. Also, you could pass the axis values squared/cubed/something exponential to give more precise slow movement ability at the expense of the less important precision when it comes to high speeds. Here is what our code currently looks like:

double leftY = (rampConstant * Math.pow(Robot.oi.getLeftY(), 3) + (1 - rampConstant) * Robot.oi.getLeftY()) * sensitivity;
double rightX = (rampConstant * Math.pow(Robot.oi.getRightX(), 3) + (1 - rampConstant) * Robot.oi.getRightX()) * (sensitivity + .15);
Robot.driveTrain.myRobot.arcadeDrive(rightX, leftY, true);

Once you have the freedom to play around with the values you send to arcade drive, you can start to customize your robot’s driving capabilities to the liking of your competition drivers.

Best of luck this year!

P.S. TimTheGreat, I like your username too man.

In addition to scaling, we also implemented a “dead zone”. So any value, say below 0.20, is treated as 0.00. That way slight touches of the joystick are ignored in that direction (you won’t have a slight veer when trying to drive straight).