Skip to main content Skip to navigation

CS313 Robot Lab 1

The purpose of the labs is to investigate how robots perform tasks in the real world. The robots used here are based on the Lego NXT platform.

You will start the labs with a pre-built Lego NXT robot. The robot will have 2 motors connected to the output ports and three sensors (a sonar sensor and two light sensors) connected to the input ports. Communication with the robot is performed over a USB connection, where you can transfer your code to the robot.

We will be using leJOS, this allows us to leJOS NXJ program the Lego NXT robots using Java. You will find the API and a number of useful tutorials here. You will be expected to explore the LeJOS API to find useful tools and methods.

Motors and DifferentialPilot

The NXTRegulatedMotor class provides access to the NXT motors. To be useful, a motor must be connected to one of the three NXT motor ports. This class provides an instance for each port. They are: Motor.A, Motor.B and Motor.C. This class provides methods for controlling the motor, and for finding out what the motor is doing.

The classes that control vehicles work at several levels of abstraction. At the bottom, there are the motors that turn the wheels, controlled by the NXTRegulatedMotor class. The DifferentialPilot class uses the motors to control simple movements such as rotating in place, travelling in a straight line, or travelling in an arc.

The DifferentialPilot class controls a vehicle that has two driving wheels, each with its own independently controlled motor. It steers the vehicle by controlling the speed and direction of rotation of its motors. By packaging a sequence of these moves together, a robot can travel from one location to another.

Getting Started

Extract and open the RobotLabMotor Project in Atom. Open the file RobotLabMotor.java. To compile and run your code you can press F9 (make sure your robot is connected via the USB 2.0 port and is turned on). Note: you may have to install the Atom Build package.

The code we have given you contains the following lines:

import lejos.nxt.Motor;
import lejos.robotics.navigation.DifferentialPilot;

public class RobotLabMotor {
public static void main(String[] args) {
DifferentialPilot pilot;
pilot = new DifferentialPilot(2.25f, 5.5f, Motor.A, Motor.C);
for(int i = 0; i<4 ; i++) {
pilot.travel(10);
pilot.rotate(90);
}
}//end class main
}//end RobotLabMotor

In the code we set up a new DifferentialPilot. The pilot object needs to know the diameter of the wheels and the width of the track (the distance between the centres of the tracks of the two wheels) - both parameters must be in the same units, but they can be anything you wish (although cm is the most sensible). The constructor also requires information about which ports the motors are connected to and whether driving the motors forward makes the robot move forward or backward (reverse). Note that your motors might not be plugged into ports Motor.A and Motor.C. You will need to set up the correct information for your robot.

The ports are labelled as shown in the image below:

nxtbrick

Once set up, we can use the travel and rotate methods to get the robot to trace out a square.

Other commonly used methods include:

  • void setTravelSpeed(double travelSpeed); //sets the speed of the motors using the same unit as the wheel diameter
  • void setRotateSpeed(double rotateSpeed); //sets the rotation speed of the vehicle, degrees per second
  • void forward(); //starts the robot moving forward
  • void backward(); //starts the robot moving backwards
  • void stop(); //stops the robot
  • void rotate (double angle); //rotates the robot a number of degrees
  • void travel (double distance); //moves the motors a specified distance using the same unit as the wheel diameter

Task 1.1 Show your robot tracing out a hexagon. You may notice that a rotation of 60 degrees in the code does not map to 60 degrees for the robot. Likewise a travel distance of 10cm in the code might not translate to 10cm for the robot. You should experiment with the travel and rotation speeds to improve the correlation between the code and the robot's behaviour in the real world.


It is important to note that debugging an NXJ robot can prove to be difficult. Any test printed through the use of System.out.println will be pushed to the screen on the NXJ brick. However you can write to text files that are stored on the NXT brick in the same way you would from a standard Java program. These are then accessed using the NXJ Browser.

When programing, be considerate of how you will validate your code is working as expected. Consider writing state checks and debug text to a file, or make use of the LeJOS debugger. Debugging will become far easier if validation is built into your code from the beginning.

An important consideration here is the limited hardware capability your robot has, which will place a constraint on the amount of data you will be able to store. It is worthwhile ensuring you regularly delete old programs and data files from your NXT brick to avoid running out of storage space.

Ultrasonic Sensors

Our robot can now move, but it needs to perform informed movements, and for that we need sensors.

The ultrasonic sensor sends out a sound signal and measures how long it takes for the reflection to return. The sensor can then use that time interval to calculate how far the signal has travelled. The ultrasonic sensor measures distances to a solid object in centimeters. Although the sensor can measure up to 255 centimeters there is a more limited range where the results are accurate. It is important to remember that the ultrasonic sensor's detection field is a cone shape. The Ultrasonic sensor is a Range Feature Detector that uses RangeFinder classes.

Extract and open the RobotLabSonic Project in Atom. Open the file RobotLabSonic.java. To compile and run your code you can press F9 (make sure your robot is connected via the USB 2.0 port and is turned on).

The code we have given you contains the following lines:

import lejos.nxt.*;

public class RobotLabSonic {
  public static void main(String[] args) throws Exception {
    UltrasonicSensor sonar = new UltrasonicSensor(SensorPort.S1);

    while (!Button.ESCAPE.isDown()) {
      LCD.drawInt(sonar.getDistance(), 0, 0);
    }//end while

  }//end class main
}//end RobotLabSonic


To use an ultrasonic sensor, you create an instance of it using the constructor. The constructor needs to know what port the sensor is plugged in to (Note: your sonar sensor may not be plugged into port S1). We then return the distance to an object and write it to the LCD screen.


Task 1.2 Show your robot is able to wander around and avoid obstacles using the ultrasonic sensor.


In this lab, you have learned about the various methods provided by the DifferentialPilot class. Based on those methods, you know how to control the movement of the robot. You have also learned about how the ultrasonic sensor works and how it can be used to give the robot obstacle avoiding capabilities.

If you have finished this lab early, feel free to move on to Lab 2.