Paul's Tutorials - logo2-2Controlling Motors



This lesson is all about making the robot actually do something beyond manage variables -- making it move.

The Motor

For the purposes of this tutorial, assume that all of the motors are Talons. The API for controlling motors is basically the same across the three more complex drive controllers (Victors, Jaguars in addition), so you won't need to worry about using different drive controllers. However, you will still need to make sure that you are declaring the correct controller.

Another thing that you should take into consideration when programming the robot's motors is the PWM of the motor that you are programming. You should always be sure that you 1) initialize the motor, and 2) initialize it on the right PWM!

For simplicity, the declaration of all of the components used in the code snippets below has been left out. You can assume the following:

/** Declarations **/
Joystick* m_gamepad;
Talon* m_arm;
Talon* m_launcher;

/** Initialization **/
m_gamepad = new Joystick (1);
m_arm = new Talon (0);
m_launcher = new Talon (1);

Moving

Controlling the drive controllers is fairly simple. For basic control, you would use the following functions:

Victor::Set(double speed)
Jaguar::Set(double speed)
Talon::Set(double speed)

Set() parameters

double speed
Relative speed of the motor, where 1.0 is full speed forward, and -1.0 is full speed reverse. Note that this depends on the orientation of the motor, and not necessarily that of the robot. Due to that, you will need to run the motor with your code to check that you have coded the proper value.

Set() use

You can use Set() in a variety of ways. If you need fine control over the speed of the motor, you would use Set() in conjunction with a GetRawAxis() call from one of your controllers (almost always controller 1 -- the joysticks on controller 0 are always reserved for driving), like so:

m_arm->Set(-m_gamepad->GetRawAxis(2)); //remember that the Y axis is backwards!!!

The above code, along with the declaration and initialization at the beginning of the lesson, sets up controller 1, a Talon for controlling an arm on PWM 0, and then uses the left Y axis to move the arm up and down.

The other way you would use Set() would be to bring a motor to a specific (relative) speed. This would be useful for powering up a launcher motor, etc. There is a way to get it to run at a more specific speed, but that will be described in thorough detail throughout the next chapter. For now, stick with this method.

In this case, you would use the controller buttons (usually A, B, X, and Y) to set the speed. B should generally be your cancel button, or speed of 0.

You might use it like this:

if (m_gamepad->GetRawButton(1)) //if the A button is pressed, full forward
    m_launcher->Set(1.0);
else if (m_gamepad->GetRawButton(3)) //if the X button is pressed, full reverse
    m_launcher->Set(-1.0);
else if (m_gamepad->GetRawButton(2)) //if the B button is pressed, cancel
    m_launcher->Set(0.0);

In this case, a button timeout would not be required, because you are setting the motor to the same value while the button is pressed.

How Fast?

If you set one motor to different speeds throughout your program, or the Set() function is controlled by a controller joystick, you may find yourself at some point needing to figure out what that motor is currently set to. There is a function for that.

float Victor::Get()
float Jaguar::Get()
float Talon::Get()

Physical Capabilities of the Robot

Now that you are programming things to move, you should, first of all, be aware that things are moving, so you should be even more certain that you and everyone around you know that the equipment you are working with can move and potentially cause serious injury. Secondly, you should be aware of the robot's physical capabilities while you are programming. For example, the 2013 bot's launcher system uses motors driving wheels via belts. If the motors spin up the belts too quickly, the belt pulleys will spin inside the belt, which in turn shreds the belt. In this case, the robot was programmed to spin up more slowly. At any rate, you should be aware of potential problems such as this and be able to work around them programmatically.

The Relay

One of the other controllers that was mentioned in lesson 1 was the Spike, which ran off of a relay. Since these devices are basically like light switches (with the added bonus of being able to go in reverse as well), they are programmed differently.

For this section, you can further assume that two relays have been set up like this:

Relay* m_roller;
Relay* m_light;
m_roller = new Relay (0);
m_light = new Relay (1);

Relay Set()

Like the other controllers, relays use the Set() function. However, it is used differently than the other functions.

Relay::Set(enum relay_state)

Relay Set() parameters

enum relay_state
the desired state of the relay, which is the following:

Again, you need to be careful, as the kForward and kReverse states are determined from the wiring and the orientation of the motor.

Relay Set() use

You would use Set() like you might expect, calling it to enable (forward or reverse) or disable the relay.

if (m_gamepad->GetRawButton(1))
	m_roller->Set(Relay::kForward);
else if (m_gamepad->GetRawButton(2))
	m_roller->Set(Relay::kReverse);
else
	m_roller->Set(Relay::kOff);

The above code will make a roller move in one direction if the A button is held, and in the other direction if the B button is held.

One thing that should be noted is that lights almost always are wired to relays (unless they are unmanaged). Because they are lights, you should only ever use the Relay:kOff and Relay::kForward states.

if (m_gamepad->GetRawButton(4))
	m_light->Set(Relay::kForward);
else
	m_light->Set(Relay::kOff);

The above code will turn a light on if the Y button is held.

What State?

Similar to the previous three, Relays also have a method to get what the controller is currently set to.

enum Relay::Get()

This returns the enumeration (from above) that represents the current state of the relay.

Activity

You will want to talk to someone who is familiar with the setup of your available robots to write something to run on a robot.

Program an available robot so that:

The sample below describes a program for the 2013 HOTBOT.

Don't forget the controller deadband (0.2), as the controllers do not zero properly. To regain fine control, add the deadband (if the controller reading is negative) / subtract the deadband (if the controller reading is positive) and then multiply that value by 1.25.


← 2-1 Using User Input 2-2 Controlling Motors 2-3 Earning Your Driver's License: Driving →