lejos.robotics.proposal
Class DifferentialPilot

java.lang.Object
  extended by lejos.robotics.proposal.DifferentialPilot
All Implemented Interfaces:
MovementProvider, ArcPilot, ArcRotatePilot, BasicPilot, RotatePilot
Direct Known Subclasses:
CarefulDifferentialPilot

public class DifferentialPilot
extends Object
implements ArcRotatePilot

The DifferentialPilot class is a software abstraction of the Pilot mechanism of a NXT robot. It contains methods to control robot movements: travel forward or backward in a straight line or a circular path or rotate to a new direction.
Note: this class will only work with two independently controlled motors to steer differentially, so it can rotate within its own footprint (i.e. turn on one spot).
It can be used with robots that have reversed motor design: the robot moves in the direction opposite to the the direction of motor rotation. Uses the TachoMotor class, which regulates motor speed using the NXT motor's built in tachometer.
It automatically updates the Pose of a robot if the Pose calls the addMoveListener() method on this class. Some methods optionally return immediately so the thread that called the method can monitor sensors, get current pose, and call stop() if necessary.
Example:

 PdifferentialPilot pilot = new DifferentialPilot(2.1f, 4.4f, Motor.A, Motor.C, true);  // parameters in inches
 pilot.setRobotSpeed(10);                                           // inches per second
 pilot.travel(12);                                                  // inches
 pilot.rotate(-90);                                                 // degree clockwise
 pilot.travel(-12,true);
 while(pilot.isMoving())Thread.yield();
 pilot.rotate(-90);
 pilot.rotateTo(270);
 pilot.steer(-50,180,true);
 while(pilot.isMoving())Thread.yield();
 pilot.steer(100);
 try{Thread.sleep(1000);}
 catch(InterruptedException e){}
 pilot.stop();
 


Field Summary
protected  boolean _alert
          should be true if an immediate return movement is in progress.
protected  TachoMotor _left
          Left motor.
protected  float _leftDegPerDistance
          Left motor degrees per unit of travel.
protected  float _leftTurnRatio
          Left motor revolutions for 360 degree rotation of robot (motors running in opposite directions).
protected  float _leftWheelDiameter
          Diameter of left wheel.
protected  float _minRadius
           
protected  int _motorSpeed
          Motor speed degrees per second.
protected  Movement.MovementType _moveType
          type of the current movement
protected  byte _parity
          Motor rotation forward makes robot move forward if parity == 1.
protected  boolean _regulating
          If true, motor speed regulation is turned on.
protected  TachoMotor _right
          Right motor.
protected  float _rightDegPerDistance
          Right motor degrees per unit of travel.
protected  float _rightTurnRatio
          Right motor revolutions for 360 degree rotation of robot (motors running in opposite directions).
protected  float _rightWheelDiameter
          Diameter of right wheel.
protected  float _robotMoveSpeed
          Speed of robot for moving in wheel diameter units per seconds.
protected  float _robotTurnSpeed
          Speed of robot for turning in degree per seconds.
protected  float _trackWidth
          Distance between wheels.
protected  ArrayList<MoveListener> listeners
          the pilot listeners
 
Constructor Summary
DifferentialPilot(float leftWheelDiameter, float rightWheelDiameter, float trackWidth, TachoMotor leftMotor, TachoMotor rightMotor, boolean reverse)
          Allocates a TachoPilot object, and sets the physical parameters of the NXT robot.
DifferentialPilot(float wheelDiameter, float trackWidth, TachoMotor leftMotor, TachoMotor rightMotor)
          Allocates a TachoPilot object, and sets the physical parameters of the NXT robot.
Assumes Motor.forward() causes the robot to move forward.
DifferentialPilot(float wheelDiameter, float trackWidth, TachoMotor leftMotor, TachoMotor rightMotor, boolean reverse)
          Allocates a TachoPilot object, and sets the physical parameters of the NXT robot.
 
Method Summary
 void addMoveListener(MoveListener aListener)
          Adds a MoveListener that will be notified of all movement events.
 void arc(float radius)
          Starts the NXT robot moving along an arc with a specified radius.
 Movement arc(float radius, float angle)
          Moves the NXT robot along an arc with a specified radius and angle, after which the robot stops moving.
 Movement arc(float radius, float angle, boolean immediateReturn)
          Moves the NXT robot along an arc with a specified radius and angle, after which the robot stops moving.
 void backward()
          Moves the NXT robot backward until stop() is called.
protected  boolean continueMoving()
          This method can be overridden by subclasses to stop the robot if a hazard is detected
 void forward()
          Moves the NXT robot forward until stop() is called.
 float getAngle()
           
 float getAngleIncrement()
           
 TachoMotor getLeft()
           
 int getLeftActualSpeed()
           
 int getLeftCount()
           
 float getMinRadius()
          The minimum steering radius this vehicle is capable of when traveling in an arc.
 float getMoveMaxSpeed()
           
 Movement getMovement()
           
 float getMovementIncrement()
           
 float getMoveSpeed()
           
 TachoMotor getRight()
           
 int getRightActualSpeed()
           
 int getRightCount()
           
 float getTravelDistance()
           
 float getTurnMaxSpeed()
           
 float getTurnRatio()
           
 float getTurnSpeed()
           
 boolean isMoving()
          true if the robot is moving
protected  void movementStart()
           
protected  void movementStop()
           
 void reset()
          Resets tacho count for both motors.
 Movement rotate(float angle)
          Rotates the NXT robot through a specific angle.
 Movement rotate(float angle, boolean immediateReturn)
          Rotates the NXT robot through a specific angle.
 void setMinRadius(float radius)
          Set the radius of the minimum turning circle
 void setMoveSpeed(float speed)
          also sets _motorSpeed
 void setSpeed(int speed)
          Sets speed of both motors, as well as moveSpeed and turnSpeed.
protected  void setSpeed(int leftSpeed, int rightSpeed)
           
 void setTurnSpeed(float speed)
           
 void steer(float turnRate)
           
 Movement steer(float turnRate, float angle)
           
 Movement steer(float turnRate, float angle, boolean immediateReturn)
           
 Movement stop()
          Stops the NXT robot.
 Movement travel(float distance)
          Moves the NXT robot a specific distance in an (hopefully) straight line.
A positive distance causes forward motion, a negative distance moves backward.
 Movement travel(float distance, boolean immediateReturn)
          Moves the NXT robot a specific distance in an (hopefully) straight line.
A positive distance causes forward motion, a negative distance moves backward.
 Movement travelArc(float radius, float distance)
          Moves the NXT robot a specified distance along an arc mof specified radius, after which the robot stops moving.
 Movement travelArc(float radius, float distance, boolean immediateReturn)
          Moves the NXT robot a specified distance along an arc of specified radius, after which the robot stops moving.
protected  int turnRate(float radius)
          Calculates the turn rate corresponding to the turn radius;
use as the parameter for steer() negative argument means center of turn is on right, so angle of turn is negative
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

_alert

protected boolean _alert
should be true if an immediate return movement is in progress. used by monitor


listeners

protected ArrayList<MoveListener> listeners
the pilot listeners


_moveType

protected Movement.MovementType _moveType
type of the current movement


_left

protected final TachoMotor _left
Left motor.


_right

protected final TachoMotor _right
Right motor.


_leftDegPerDistance

protected final float _leftDegPerDistance
Left motor degrees per unit of travel.


_rightDegPerDistance

protected final float _rightDegPerDistance
Right motor degrees per unit of travel.


_leftTurnRatio

protected final float _leftTurnRatio
Left motor revolutions for 360 degree rotation of robot (motors running in opposite directions). Calculated from wheel diameter and track width. Used by rotate() and steer() methods.


_rightTurnRatio

protected final float _rightTurnRatio
Right motor revolutions for 360 degree rotation of robot (motors running in opposite directions). Calculated from wheel diameter and track width. Used by rotate() and steer() methods.


_robotMoveSpeed

protected float _robotMoveSpeed
Speed of robot for moving in wheel diameter units per seconds. Set by setSpeed(), setMoveSpeed()


_robotTurnSpeed

protected float _robotTurnSpeed
Speed of robot for turning in degree per seconds.


_motorSpeed

protected int _motorSpeed
Motor speed degrees per second. Used by forward(),backward() and steer().


_parity

protected byte _parity
Motor rotation forward makes robot move forward if parity == 1.


_regulating

protected boolean _regulating
If true, motor speed regulation is turned on. Default = true.


_trackWidth

protected final float _trackWidth
Distance between wheels. Used in steer() and rotate().


_leftWheelDiameter

protected final float _leftWheelDiameter
Diameter of left wheel.


_rightWheelDiameter

protected final float _rightWheelDiameter
Diameter of right wheel.


_minRadius

protected float _minRadius
Constructor Detail

DifferentialPilot

public DifferentialPilot(float wheelDiameter,
                         float trackWidth,
                         TachoMotor leftMotor,
                         TachoMotor rightMotor)
Allocates a TachoPilot object, and sets the physical parameters of the NXT robot.
Assumes Motor.forward() causes the robot to move forward.

Parameters:
wheelDiameter - Diameter of the tire, in any convenient units (diameter in mm is usually printed on the tire).
trackWidth - Distance between center of right tire and center of left tire, in same units as wheelDiameter.
leftMotor - The left Motor (e.g., Motor.C).
rightMotor - The right Motor (e.g., Motor.A).

DifferentialPilot

public DifferentialPilot(float wheelDiameter,
                         float trackWidth,
                         TachoMotor leftMotor,
                         TachoMotor rightMotor,
                         boolean reverse)
Allocates a TachoPilot object, and sets the physical parameters of the NXT robot.

Parameters:
wheelDiameter - Diameter of the tire, in any convenient units (diameter in mm is usually printed on the tire).
trackWidth - Distance between center of right tire and center of left tire, in same units as wheelDiameter.
leftMotor - The left Motor (e.g., Motor.C).
rightMotor - The right Motor (e.g., Motor.A).
reverse - If true, the NXT robot moves forward when the motors are running backward.

DifferentialPilot

public DifferentialPilot(float leftWheelDiameter,
                         float rightWheelDiameter,
                         float trackWidth,
                         TachoMotor leftMotor,
                         TachoMotor rightMotor,
                         boolean reverse)
Allocates a TachoPilot object, and sets the physical parameters of the NXT robot.

Parameters:
leftWheelDiameter - Diameter of the left wheel, in any convenient units (diameter in mm is usually printed on the tire).
rightWheelDiameter - Diameter of the right wheel. You can actually fit intentionally wheels with different size to your robot. If you fitted wheels with the same size, but your robot is not going straight, try swapping the wheels and see if it deviates into the other direction. That would indicate a small difference in wheel size. Adjust wheel size accordingly. The minimum change in wheel size which will actually have an effect is given by minChange = A*wheelDiameter*wheelDiameter/(1-(A*wheelDiameter) where A = PI/(moveSpeed*360). Thus for a moveSpeed of 25 cm/second and a wheelDiameter of 5,5 cm the minChange is about 0,01058 cm. The reason for this is, that different while sizes will result in different motor speed. And that is given as an integer in degree per second.
trackWidth - Distance between center of right tire and center of left tire, in same units as wheelDiameter.
leftMotor - The left Motor (e.g., Motor.C).
rightMotor - The right Motor (e.g., Motor.A).
reverse - If true, the NXT robot moves forward when the motors are running backward.
Method Detail

addMoveListener

public void addMoveListener(MoveListener aListener)
Description copied from interface: MovementProvider
Adds a MoveListener that will be notified of all movement events.

Specified by:
addMoveListener in interface MovementProvider
Parameters:
aListener - the move listener

getLeft

public TachoMotor getLeft()
Returns:
left motor.

getRight

public TachoMotor getRight()
Returns:
right motor.

getLeftCount

public int getLeftCount()
Returns:
tachoCount of left motor. Positive value means motor has moved the robot forward.

getRightCount

public int getRightCount()
Returns:
tachoCount of the right motor. Positive value means motor has moved the robot forward.

getLeftActualSpeed

public int getLeftActualSpeed()
Returns:
actual speed of left motor in degrees per second. A negative value if motor is rotating backwards. Updated every 100 ms.

getRightActualSpeed

public int getRightActualSpeed()
Returns:
actual speed of right motor in degrees per second. A negative value if motor is rotating backwards. Updated every 100 ms.

getTurnRatio

public float getTurnRatio()
Returns:
ratio of motor revolutions per 360 degree rotation of the robot. If your robot has wheels with different size, it is the average.

setSpeed

public void setSpeed(int speed)
Sets speed of both motors, as well as moveSpeed and turnSpeed. Only use if your wheels have the same size.

Parameters:
speed - The wanted speed in degrees per second.

setSpeed

protected void setSpeed(int leftSpeed,
                        int rightSpeed)

setMoveSpeed

public void setMoveSpeed(float speed)
also sets _motorSpeed

Specified by:
setMoveSpeed in interface BasicPilot
See Also:
Pilot.setMoveSpeed(float)

getMoveSpeed

public float getMoveSpeed()
Specified by:
getMoveSpeed in interface BasicPilot
See Also:
Pilot.getMoveSpeed()

getMoveMaxSpeed

public float getMoveMaxSpeed()
Specified by:
getMoveMaxSpeed in interface BasicPilot
See Also:
Pilot.getMoveMaxSpeed()

setTurnSpeed

public void setTurnSpeed(float speed)
Specified by:
setTurnSpeed in interface RotatePilot
See Also:
Pilot.setTurnSpeed(float)

getTurnSpeed

public float getTurnSpeed()
Specified by:
getTurnSpeed in interface RotatePilot
See Also:
Pilot.getTurnSpeed()

getTurnMaxSpeed

public float getTurnMaxSpeed()
Specified by:
getTurnMaxSpeed in interface RotatePilot
See Also:
Pilot.getTurnMaxSpeed()

isMoving

public boolean isMoving()
Description copied from interface: BasicPilot
true if the robot is moving

Specified by:
isMoving in interface BasicPilot
Returns:
true if the NXT robot is moving.

getTravelDistance

public float getTravelDistance()
Returns:
distance traveled since last movement started.

getAngle

public float getAngle()
Returns:
the angle of rotation of the robot since last started tacho count;

reset

public void reset()
Resets tacho count for both motors.


forward

public void forward()
Moves the NXT robot forward until stop() is called.

Specified by:
forward in interface BasicPilot

backward

public void backward()
Moves the NXT robot backward until stop() is called.

Specified by:
backward in interface BasicPilot

rotate

public Movement rotate(float angle)
Rotates the NXT robot through a specific angle. Returns when angle is reached. Wheels turn in opposite directions producing a zero radius turn.
Note: Requires correct values for wheel diameter and track width.

Specified by:
rotate in interface RotatePilot
Parameters:
angle - The wanted angle of rotation in degrees. Positive angle rotate left (clockwise), negative right.

rotate

public Movement rotate(float angle,
                       boolean immediateReturn)
Rotates the NXT robot through a specific angle. Returns when angle is reached. Wheels turn in opposite directions producing a zero radius turn.
Note: Requires correct values for wheel diameter and track width.

Specified by:
rotate in interface RotatePilot
Parameters:
angle - The wanted angle of rotation in degrees. Positive angle rotate left (clockwise), negative right.
immediateReturn - If true this method returns immediately.

continueMoving

protected boolean continueMoving()
This method can be overridden by subclasses to stop the robot if a hazard is detected

Returns:
true iff no hazard is detected

stop

public Movement stop()
Stops the NXT robot.

Specified by:
stop in interface BasicPilot
Returns:
The movement it just achieved?

travel

public Movement travel(float distance)
Moves the NXT robot a specific distance in an (hopefully) straight line.
A positive distance causes forward motion, a negative distance moves backward. If a drift correction has been specified in the constructor it will be applied to the left motor.

Specified by:
travel in interface BasicPilot
Parameters:
distance - The distance to move. Unit of measure for distance must be same as wheelDiameter and trackWidth.

travel

public Movement travel(float distance,
                       boolean immediateReturn)
Moves the NXT robot a specific distance in an (hopefully) straight line.
A positive distance causes forward motion, a negative distance moves backward. If a drift correction has been specified in the constructor it will be applied to the left motor.

Specified by:
travel in interface BasicPilot
Parameters:
distance - The distance to move. Unit of measure for distance must be same as wheelDiameter and trackWidth.
immediateReturn - If true this method returns immediately.

steer

public void steer(float turnRate)

steer

public Movement steer(float turnRate,
                      float angle)

steer

public Movement steer(float turnRate,
                      float angle,
                      boolean immediateReturn)

arc

public void arc(float radius)
Description copied from interface: ArcPilot
Starts the NXT robot moving along an arc with a specified radius.

If radius is positive, the robot arcs left, and the center of the turning circle is on the left side of the robot.
If radius is negative, the robot arcs right, and the center of the turning circle is on the right side of the robot.
If radius is zero, the robot rotates in place.

Postcondition: Motor speeds are unpredictable.

Note: If you have specified a drift correction in the constructor it will not be applied in this method.

Specified by:
arc in interface ArcPilot
Parameters:
radius - of the arc path. If positive, the left side of the robot is on the inside of the turn. If negative, the left side of the robot is on the outside of the turn.

arc

public Movement arc(float radius,
                    float angle)
Description copied from interface: ArcPilot
Moves the NXT robot along an arc with a specified radius and angle, after which the robot stops moving. This method does not return until the robot has completed moving angle degrees along the arc.

If radius is positive, the robot arcs left, and the center of the turning circle is on the left side of the robot.
If radius is negative, the robot arcs right, and the center of the turning circle is on the right side of the robot.
If radius is zero, is zero, the robot rotates in place.

Robot will stop when the degrees it has moved along the arc equals angle.
If angle is positive, the robot will move travel forwards.
If angle is negative, the robot will move travel backwards. If angle is zero, the robot will not move and the method returns immediately.

Postcondition: Motor speeds are unpredictable.

Note: If you have specified a drift correction in the constructor it will not be applied in this method.

Specified by:
arc in interface ArcPilot
Parameters:
radius - of the arc path. If positive, the left side of the robot is on the inside of the turn. If negative, the left side of the robot is on the outside of the turn.
angle - The sign of the angle determines the direction of robot motion. Positive drives the robot forward, negative drives it backward.
See Also:
ArcPilot.travelArc(float, float)

arc

public Movement arc(float radius,
                    float angle,
                    boolean immediateReturn)
Description copied from interface: ArcPilot
Moves the NXT robot along an arc with a specified radius and angle, after which the robot stops moving. This method has the ability to return immediately by using the immediateReturn parameter.

If radius is positive, the robot arcs left, and the center of the turning circle is on the left side of the robot.
If radius is negative, the robot arcs right, and the center of the turning circle is on the right side of the robot.
If radius is zero, is zero, the robot rotates in place.

The robot will stop when the degrees it has moved along the arc equals angle.
If angle is positive, the robot will move travel forwards.
If angle is negative, the robot will move travel backwards. If angle is zero, the robot will not move and the method returns immediately.

Postcondition: Motor speeds are unpredictable.

Note: If you have specified a drift correction in the constructor it will not be applied in this method.

Specified by:
arc in interface ArcPilot
Parameters:
radius - of the arc path. If positive, the left side of the robot is on the inside of the turn. If negative, the left side of the robot is on the outside of the turn.
angle - The sign of the angle determines the direction of robot motion. Positive drives the robot forward, negative drives it backward.
immediateReturn - If immediateReturn is true then the method returns immediately and your code MUST call updatePostion() when the robot has stopped. Otherwise, the robot position is lost.
See Also:
ArcPilot.travelArc(float, float, boolean)

travelArc

public Movement travelArc(float radius,
                          float distance)
Description copied from interface: ArcPilot
Moves the NXT robot a specified distance along an arc mof specified radius, after which the robot stops moving. This method does not return until the robot has completed moving distance along the arc. The units (inches, cm) for distance must be the same as the units used for radius.

If radius is positive, the robot arcs left, and the center of the turning circle is on the left side of the robot.
If radius is negative, the robot arcs right, and the center of the turning circle is on the right side of the robot.
If radius is zero, the robot rotates in place

The robot will stop when it has moved along the arc distance units.
If distance is positive, the robot will move travel forwards.
If distance is negative, the robot will move travel backwards. If distance is zero, the robot will not move and the method returns immediately.

Postcondition: Motor speeds are unpredictable.

Note: If you have specified a drift correction in the constructor it will not be applied in this method.

Specified by:
travelArc in interface ArcPilot
Parameters:
radius - of the arc path. If positive, the left side of the robot is on the inside of the turn. If negative, the left side of the robot is on the outside of the turn.
distance - to travel, in same units as radius. The sign of the distance determines the direction of robot motion. Positive drives the robot forward, negative drives it backward.
See Also:
ArcPilot.arc(float, float)

travelArc

public Movement travelArc(float radius,
                          float distance,
                          boolean immediateReturn)
Description copied from interface: ArcPilot
Moves the NXT robot a specified distance along an arc of specified radius, after which the robot stops moving. This method has the ability to return immediately by using the immediateReturn parameter. The units (inches, cm) for distance should be the same as the units used for radius. Warning: Your code must call updatePostion() when the robot has stopped, otherwise, the robot position is lost.

If radius is positive, the robot arcs left, and the center of the turning circle is on the left side of the robot.
If radius is negative, the robot arcs right, and the center of the turning circle is on the right side of the robot.
If radius is zero, ...

The robot will stop when it has moved along the arc distance units.
If distance is positive, the robot will move travel forwards.
If distance is negative, the robot will move travel backwards. If distance is zero, the robot will not move and the method returns immediately.

Postcondition: Motor speeds are unpredictable.

Note: If you have specified a drift correction in the constructor it will not be applied in this method.

Specified by:
travelArc in interface ArcPilot
Parameters:
radius - of the arc path. If positive, the left side of the robot is on the inside of the turn. If negative, the left side of the robot is on the outside of the turn.
distance - to travel, in same units as radius. The sign of the distance determines the direction of robot motion. Positive drives the robot forward, negative drives it backward.
immediateReturn - If immediateReturn is true then the method returns immediately and your code MUST call updatePostion() when the robot has stopped. Otherwise, the robot position is lost.
See Also:
ArcPilot.arc(float, float, boolean)

turnRate

protected int turnRate(float radius)
Calculates the turn rate corresponding to the turn radius;
use as the parameter for steer() negative argument means center of turn is on right, so angle of turn is negative

Parameters:
radius -
Returns:
steer()

movementStart

protected void movementStart()

movementStop

protected void movementStop()

setMinRadius

public void setMinRadius(float radius)
Description copied from interface: ArcPilot
Set the radius of the minimum turning circle

Specified by:
setMinRadius in interface ArcPilot
Parameters:
radius - the radius in degrees

getMinRadius

public float getMinRadius()
Description copied from interface: ArcPilot
The minimum steering radius this vehicle is capable of when traveling in an arc. Theoretically this should be identical for both forward and reverse travel. In practice?

Specified by:
getMinRadius in interface ArcPilot
Returns:
the radius in degrees

getMovement

public Movement getMovement()
Specified by:
getMovement in interface MovementProvider

getMovementIncrement

public float getMovementIncrement()
Specified by:
getMovementIncrement in interface BasicPilot

getAngleIncrement

public float getAngleIncrement()
Specified by:
getAngleIncrement in interface RotatePilot