Combining Commands

Now that we have commands to drive and turn let’s see how we can combine them to create more complex commands. Let’s create a new command that will drive the robot around a certain path.  The first step is to create a new command called DriveCourseCommand. This type of command has a different structure so this time instead of copying the ExampleCommand we are going to make this new class inherit from SequentialCommandGroup instead of Command.

To create the new class, right click on the commands folder, choose New File, and enter the name DriveCourseCommand.java. Then replace the text in that file with:

Key differences in what we’ve been doing is that 1) we inherit from SequentialCommandGroup and 2) we do not have the usual command functions (e.g. initialize, execute, etc.). This is because this command will be composed of a set of commands (a composite command).

To start, let’s say we want to drive forward 20 inches and then turn right by 90 degrees, we would add the following lines to the constructor:

Notice how I placed the built in WaitCommand between the DriveForDistanceCommand and TurnCommand. The WaitCommand does nothing but wait for a specified time. Adding a small wait between the commands will increase the accuracy of the turns. Transitioning directly from driving to turning can cause errors like wheel slippage which will throw off our turn calculations. I am also using variables turn90, speed, and wait rather than specifying the numbers directly in the respective constructors. I am doing this since we will be adding multiple commands that use these numbers and defining them all in one place will make it easier for us to adjust the numbers if needed.

Now modify the RobotContainer class so that we run this new command when we press our test button 6.

Now deploy and run your program and verify that it drives forward 20 inches, turns right and then stops. Adjust the turn90 variable so that the turn is correct.

Now let’s change your program so that the robot will drive in a rectangular pattern 20 inches by 10 inches. In principle this should bring your robot back to the starting position. After you have completed and tested your code, compare it to my solution below.

.

.

.

.

.

.

Note that in my case I needed set the turn90 to 85 degrees instead of 90 in order to get the robot to drive the correct path. You will probably find that it was very hard to set the speed and turn parameters correctly to bring the robot back to the exact starting position. In fact, you probably saw that running the same program twice in a row actually produced a slightly different outcome. This is because there are a number of things that go on which introduce slight errors (such as wheel slippage), and these errors accumulate over time and are different every time. You might find that if you slow the robot down, you can get more reproducible results, but you can never reach the point where it is always spot on.

The important take-away from this: This kind of ‘dead reckoning’ navigation is fraught with problems. The only way to overcome these problems is to use sensors (e.g. gyro, distance sensor, camera, etc.) on the robot that give you a way to determine it’s absolute position and orientation by observing and using the environment around it. This is how the competition robots determine their position on the field.

Next: Using Sensors