you're reading...
leJOS Features, Moving around

leJOS Navigation: Pilots

This is the first of a series of posts on leJOS Navigation features.

This post concentrates on how to move a mobile robot around.

leJOS provides features for two-dimensional navigation, i.e. moving a robot around on a surface such as a the floor in your house or the ground outside. The leJOS navigation classes would not be much good for navigation of drones in three dimensions, but then building a drone out of LEGO would be a bit of a challenge. The classes could probably be used for navigating boats on water, but weren’t really designed for that. They are really designed for moving wheeled or legged robots around, and most of the implementation concentrates on wheeled vehicles.

leJOS provides an interface called MoveController. If you want to use the leJOS navigation classes to move your robot around, you will need a class that implements MoveController. You can either write your own or use one of the standard leJOS pilot classes. leJOS refers to a class that implements MoveController as a pilot.

Here is an example program that uses MoveController. It makes use of the DifferentialPilot class described below, but you could write your own much simpler MoveController that does this The program drives a wheeled robot up to an obstacle such as a wall, detects the wall, and then drives back to its starting position.

import lejos.hardware.motor.Motor;
import lejos.hardware.port.SensorPort;
import lejos.hardware.sensor.EV3IRSensor;
import lejos.robotics.SampleProvider;
import lejos.robotics.navigation.DifferentialPilot;
import lejos.robotics.navigation.MoveController;

 * Robot travels to obstacle and back again
public class TravelTest {
  MoveController pilot;
  EV3IRSensor ir = new EV3IRSensor(SensorPort.S4);
  SampleProvider bump = ir.getDistanceMode();
  float[] sample = new float[1];

  public void go() {
    while (pilot.isMoving()) {
      bump.fetchSample(sample, 0);
      if (sample[0] < 20) pilot.stop();
    float dist = pilot.getMovement().getDistanceTraveled();
    System.out.println("Distance = " + dist);

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

A vanilla MoveController isn’t much use to you, however. It has the methods forward, backward and stop to move your robot forwards and backwards, and you can set the speed by setTravelSpeed. You can also use the travel methods to move your robot a specified distance. But this is just one-dimensional navigation! There are no methods to turn your robot.

Before we look at ways to turn your robot to allow two-dimensional navigation, lets look at a few points on how MoveController works.

Firstly, note that there are no defined units for how distance is measured. The travel methods can use any units, such as centimeters, inches, meters or any other unit you want. You just have to be consistent. Once you have decided on a distance unit, the speed set by setTravelSpeed and returned by getTravelSpeed is in units per second.

Secondly, note that you get a choice about whether methods block or not. The travel(double distance, boolean immediateReturn) method lets you specify whether you want immediate return from the method or not. If you specify false for the parameter, control will not return to you until the robot has moved the specified distance. If you specify true, control will return immediately and you can do other things in the same thread, such as checking for obstacles, while your robot is moving.

Thirdly, note that MoveController does not use a co-ordinate system. You can use pilots to move robots around without worrying about (x,y) or any other co-ordinates. Co-ordinates will be introduced when we look at pose providers.

Fourthly, a MoveController generates a Move object for every move that it makes. A Move object gives you details of the move made including the distance traveled and the angle turned. It gives you access to the Move object by extending the interface MoveProvider. MoveProvider gives you access to the move in two ways. You can call the getMoveMent method to get details of the current move or the last completed move if no move is in progress. (You can see if a move is in progress by calling the isMoving method of MoveControlller). The other way to get access to a completed move is to register a MoveListener with the MoveProvider. The MoveListener moveStarted and moveStopped methods are called when a move starts and stops.

Now that we have got those points out of the way, we can look at proper two-dimensional navigation.

The reason that MoveController does not have methods for turning your robot, is that different types of robot have different ways of turning or steering. In particular, some robots can turn on the spot, but others can only steer like a car, in arcs.

So there are three interfaces that extend MoveController: RotateMoveController, ArcMoveController and ArcRotateMoveController.

RotateMoveController introduces the rotate methods that let you rotate the robot on the spot by a specified angle. It also introduces methods to set and get the rotation speed, and to get the maximum rotation speed supported by the robot.

ArcMoveController introduces method to travel in arcs.

ArcRotateMoveController includes the methods from RotateMoveController and ArcMoveController, as some robots can either turn on the spot, or traverse arcs.

Now that we have looked at the interfaces, it is time to look at the pilot classes that leJOS provides.

The main one we are going to look at is DifferentialPilot. This class drives wheeled robots that have two independently drivable wheels, i.e. that support differential steering.

DifferentialPilot implements the ArcRotateMoveConroller interface, as vehicles with differential steering can turn on the spot and can drive in arcs.

Wheeled robots that implement differential steering can vary a lot. They can have different sized wheels, and the track width between the wheels can vary. Also, you get a choice of four motor ports for connecting your two motors to. Finally, the way the robot is constructed can affect whether the robot moves backwards or forwards when its motors move forward. For this reason, the constructors for DifferentialPilot let you define the wheel diameter and track width, let you specify which regulated motors to use to drive the left and right wheels, and have a reverse parameter that specifies whether moving the motors forward causes the robot to reverse or not.

A good test of the DifferentialPilot class is the PilotTester sample. PilotTester lets you pick up the constructor parameters for DifferentialPilot from a properties file, and the PilotParams sample lets you create such a file, but you can create it with a text editor.

To use PilotTester, set up your pilot.props file, put your pilot on the floor at least one hundred units from any obstacle in any direction, and press the Enter button. Your robot will do a sequence of travel, rotate and arc moves, and should end up roughly where is started.

A good robot to use for this test is the TRACK3R robot, but you can use any wheeled robot with differential steering.

leJOS provides pilot implementations for other types of wheeled vehicles. CompassPilot is an extention to DifferentialPilot which includes a compass sensor to help keep the heading of the robot accurate while it is moving around.

SteeringPilot supports wheeled vehicles that use car steering, e.g. they use one motor for a pair of drive wheels and another motor to turn a pair of wheels used for steering. Car steering does not allow turning on the spot, so SteeringPilot implements ArcMoveController, not ArcRotateMoveController.

OmniPilot supports holonomic robots that can move in any direction, such as a BallBot.



One thought on “leJOS Navigation: Pilots

  1. Thanks for the great articles! Really helping me understand the documentation!

    Posted by RD | 2016/10/20, 13:24

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

About leJOS News

leJOS News keeps you up-to-date with leJOS. It features latest news, explains cool features, shows advanced techniques and highlights amazing projects. Be sure to subscribe to leJOS News and never miss an article again. Best of all, subscription is free!
Follow leJOS News on WordPress.com
%d bloggers like this: