Controlling Wheeled Vehicles

Controlling Wheeled Vehicles

A common type of robot is the two wheeled vehicle with independently controlled motors. This design uses differential steering and can turn in place. leJOS NXJ contains several classes that control it.

#### Pilot

The Pilot class steers the vehicle by controlling the speed and direction of rotation of its motors. The pilot needs to know the wiring diagram of the robot, i.e. which ports the motors are connected to and whether driving the motors forward makes the robot move forward or backward (reverse). It also needs to know the diameter of the wheels and the width of the track, i.e. the distance between the centres of the tracks of the two wheels. The Pilot uses the wheel diameter to calculate the distance it has traveled. It uses the ratio to calculate how far it has rotated. Obviously, both parameters must be in the same units, but they can be anything you wish. With proper adjustment of these parameters, errors in distance traveled and angle of rotation can be held do 2% or perhaps less. This information is passed to the pilot constructor.

##### Constructors:

• Pilot(float wheelDiameter, float trackWidth,M otor leftMotor, Motor rightMotor)

• Pilot(float wheelDiameter, float trackWidth, Motor leftMotor, Motor rightMotor, boolean reverse)

Use this constructor if you need to set the reverse boolean to true.

##### Straight line movement

To control the robot moving in a straight line, use:

• void setSpeed(int speed)

sets the speed of the motors in degrees/second

• void forward()

starts the robot moving forward

• void backward()

• void stop()

To control the distance the robot moves, use:

• void travel(float distance)

• void travel(float distance, boolean immediateReturn)

distance is in the same units as wheel diameter; a negative distance means travel backwards. You can find out how far the robot has moved by calling

• int getTravelDistance(); - returns the distance traveled since the last call to resetTachoCount();

Example:

``````
import lejos.nxt.*;

/**
* Robot that stops if it hits something before it completes its travel.
*/
public class TravelTest {
Pilot pilot;
TouchSensor bump = new TouchSensor(SensorPort.S1);

public void go() {
pilot.travel(20, true);
while (pilot.isMoving()) {
if (bump.isPressed()) pilot.stop();
}
System.out.println(" "+pilot.getTravelDistance());
Button.ewaitForPress();
}

public static void main(String[] args) {
TravelTest traveler = new TravelTest();
traveler.pilot = new Pilot(2.25f, 5.5f, Motor.A, Motor,C);
traveler.go();
}
}
``````

You can cause the robot to rotate in place by a specified angle by using

• void rotate(int degrees)

You must have accurate values for wheelDiameter and trackWidth for this method to produce accurate results.

##### Program SquareTracer

Write a program that uses a Pilot to trace out a square, using the travel and rotate methods.

Solution

##### Program SquareTracer2

Write a program that traces 2 squares with increasing angle at the corners, then retraces the same path in the opposite direction.. Modify the traceSquare method of program Pilot 1 so it can trace a square in either direction, and use it in this program. This is stringent test of the accuracy of the wheel diameter and track width constants you use in you pilot.

Solution

##### Movement along a curved path

The pilot can turn the robot in place by driving one wheel forward and the other backward. The methods that do it are:

• void rotate(int angle)

• void rotate(int angle, boolean immediateReturn )

If angle is positive, the robot turns to the left. The immediateReturn parameter works as in the Motor methods –allowing the calling thread to do other work while the rotation task in progress.

The Pilot can also control the robot to move in a circular path using these methods:

• void steer(int turnRate) – follows a circular path until another method is executed

• void steer(int turnRate, int angle)

• void steer(int turnRate, int angle, boolean immediateReturn)

The turnRate parameter determines the radius of the path. A positive value means that center of the circle is to the left of the robot (so the left motor drives the inside wheel). A negative value means the left motor is the outside wheel. The absolute value is between 0 and 200, and this determines the ratio of inside to outside motor speed. The outside motor runs at the set speed of the robot; the inner motor is slowed down to make the robot turn. At turn rate 0, the speed ratio is 1.0 and the robot travels in a straight line. At turn rate 200, the speed ratio is -1 and the robot turns in place. Turn rate 100 gives speed ratio 0, so the inside motor stops. The formula is: speed ratio = 100 - abs(turnRate).

The angle parameter determines the rotation angle at which the robot stops. If the angle is negative, the robot follows the circular path defined by the turn rate, but it moves backwards.

• getAngle() - returns the angle of vehicle rotation since the last call of resetTachoCount()

##### Program SteerTester

Write a program that uses the ButtonCounter to enter the turn rate and angle variables, and then calls the steer() method. It does this in a loop so you can try different values of these parameters to control the robot path.

Solution

##### Other methods for Pilot

• void resetTachocount()

Resets both motors. This method is NOT called by any other Pilot methods. You must call this method if you want useful results from getTravelDistance() or getAngle();

• void regulateSpeed(Boolean yes)

You should consider turning off speed regulation if you are using sensor feedback and the steer() method to control the robot movement.

• boolean isMoving()

Returns true if either motor is moving. Useful if you have used the immediateReturn parameter and need to know if the task is still in progress.

• boolean stalled()

returns true if either motor actual speed is zero. Remember, the actual speed is calculated every 100ms. So stalled() will return true for the first 100ms after the robot begins its move.

If you really need to deal with individual motors, you can use:

• Motor getLeft()

• Motor getRight()

#### Compass Pilot

The CompassPilot is an extension of the Pilot class. It implements the same methods, but uses a Compass Sensor to ensure that the pilot does not deviate from the correct angle of robot heading.

It needs a HiTechnic or Mindsensors compass sensor plugged in to one of the sensor ports. Its constructors are similar those of Pilot, but with the additional information of the compass sensor port.

##### Constructors:

• CompassPilot(SensorPort compassPort, float wheelDiameter,float trackWidth,Motor leftMotor, Motor rightMotor)

• CompassPilot(SensorPort compassPort, float wheelDiameter,float trackWidth,Motor leftMotor, Motor rightMotor, boolean reverse)

• void calibrate()

calibrate the compass sensor; rotates the robot slowly through 360 degreees.

set the desired robot heading, in degrees in Cartesian coordinates (a left turn increases the heading)

• int getAngle()

return the compass Cartesian angle. Also the actual robot heading assuming the compass sensor points forward.

Write a program that does these steps:

1. Calibrate the compass.

2. Rotate the robot to a heading or 90 degrees

3. Reset the Cartesian zero of the compass sensor to correspond the current heading.

4. Move the robot a fixed distance forward.

5. Rotate 90 degrees to the left.

6. Move the robot the same distance backwards.

7. Display the compass reading and the distance traveled at the end of each move.

Suggestion: while the robot is moving, nudge it off course and watch it steer back to the correct heading.

Solution

#### Tacho Navigator

There are three abstraction layers of classes that control two wheeled vehicles. This architecture allows you to pick the layer that most useful for your application and not be concerned with the lower layers.

The Tacho Navigator implements the Navigator interface which defines methods for the basic navigational tasks. The navigator keeps track of the robot’s coordinates (x, and y) and its heading angle (the direction it is facing ). It uses Cartesian coordinates, with angles in degrees; 0 degrees is the direction of the positive x axis, 90 degrees is the positive y axis. Since a TachoNavigator needs a Pilot to control the vehicle, it implements the common Pilot movement commands that you might want to use.

##### Constructors:

• TachoNavigator(Pilot aPilot)

To use this constructor, you must construct a pilot and use it as the parameter.

Alternatively, you can use a constructor that creates a pilot from the information you supply. The parameter list is the same as in the Pilot constructors.

• TachoNavigator(float wheelDiameter,,float trackWidth, Motor leftMotor, Motor rightMotor)

• TachoNavigator(float wheelDiameter,,float trackWidth, Motor leftMotor Motor rightMotor,boolean reverse)

Methods to set and get the robot position and its components:

• void setPosition(float x, float y, float directionAngle)

• float getX()

• float getY()

• float getAngle()

Methods to get the angle and distance to a point with coordinates (x,y):

• float angleTo(float x, float y)

• float distanceTo(float x, float y)

Updating the robot position (x,y and angle)

• void updatePosition()

Updates robot location (x,y) and direction angle. Called by stop, and movement commands that do not exit until the robot has stopped. If you use a movement command that returns immediately, you MUST call this method when the movement is complete. It may also be called while movement is in progress so you can then call methods to get the components of the robot position.

##### Controlling the robot movement in the plane

As with the Pilot class, the Navigator movement control methods have two versions. One version returns only after the movement is complete and the robot position has been updated. The other version has the option of initiating the movement and returning immediately. When you use this option, you must be sure the robot position is updated before it moves again.

The methods that automatically call updatePosition() before returning are:

• void stop()

• void travel(float distance)

• void rotate(float angle)

• void rotateTo(float angle)

• goTo(float x, float y)

This method drives the robot in the arc of a circle. {It calls pilot.steer().} If the radius is negative, the center of the turn is on the right side of the robot. If angle is negative, the robot travels backwards.

The methods that require you to call updatePosition when the movement is complete include the methods when called with immediateReturn set to true

• void travel(float distance, boolean immediateReturn)

• void rotate(float angle, boolean immediateReturn)

• void rotateTo(float angle, boolean immediateReturn)

• goTo(float x, float y , boolean immediateReturn)

• turn(float radius, float angle, boolean immediateReturn)

• forward()

• backward()

• rotateLeft()

• rotateRight()

##### Program: Tacho Navigator Test

Write a program that performs the following steps:

1. Set the speed to 500, and the initial heading to 90 degrees (pointing along the y axis)

2. Travel to the point (-10,0).

3. Travel to (10,20).

while moving, display the x and y coordinates every half second, in a new row each time.

Solution.

#### Compass Navigator

The compass navigator is a sub class of TachoNavigator, and as such, implements all the TachoNavigator methods.

##### Constructors:

• CompassNavigator(CompassPilot aPilot)

To use this constructor, you must construct a pilot and use it as the parameter.

Alternatively, you can use a constructor that creates a pilot from the information you supply. The parameter list is the same as in the CompassPilot constructors.

• CompassNavigator(SensorPort compassPort ,float wheelDiameter, float trackWidth, Motor leftMotor, Motor rightMotor)

• CompassNavigator(SensorPort compassPort ,float wheelDiameter, float trackWidth, Motor leftMotor, Motor rightMotor, boolean reverse)

##### Other Methods:

• void calibrate()

This method merely calls the same method on the CompassPilot.