Eric Zielinski
Dr. Bi
CMPS 358
16, February 2014
Assignment 1
The Gyro Sensor is a part usable with the LEGO Mindstorm Real Time System that enables it to detect both the position of the system (relative to its starting position) and the rate at which its direction is changing (in degrees-per-second). These readings are accurate to within three degrees. Knowing this rate of change, referred to as “angular velocity,” and the current orientation of the system are of incredible use in constructing a moving robot. The uses of these features are extremely important in many areas, such as trying to keep a system moving in a straight line at a steady pace, having it turn in a way that will keep it from crashing, or following a specified path properly.
The physical Sensor is relatively easy to find and connect to the rest of the system. It is a sensor, and thus must be connected to the 1/2/3/4 ports (rather than the a/b/c/d ports used for motors and other actuators) via the standard wires used for all attachments to the brick. Below is a picture of the Gyro Sensor for your convenience:
On the software end of things, using the Gyro Sensor is relatively straightforward. Only two packages need to be imported: the ports that the brick is connected to and the Gyro Sensor itself. The import statements to import these are
importlejos.hardware.port.Port;
and
importlejos.hardware.sensor.EV3GyroSensor;
To construct the Gyro Sensor, you simply have to declare an instance of it as you would any object in Java: EV3GyroSensor *nameOfInstanceVariable* = newEV3GyroSensor(*portThatPhysicalGyroSensorIsConnectedTo*);
It should be noted that the description of the port that is entered as the parameter for the constructor can be either a standard port or a “UART port.” UART stands for “Universal Asynchronous Receiver/Transmitter, and UART ports are used when translating data between parallel form (in which many bits of data are communicated between two processes at the same time) and serial form (in which data is communicated one bit at a time).
The process ofinitializing and declaring the Gyro Sensor is roughly the same as it is for any other sensor. You follow the syntax EV3GyroSensor *name* = new EV3GyroSensor(*port you’re using*). An example is shown below,
EV3GyroSensor Gyro = new EV3GyroSensor(SensorPort.S1);
The Gyro Sensor as it appears in EV3 has 3 modes. “Gyro.getAngleMode()” returns the orientation of the sensor in whole degrees. Counter-intuitively, Clockwise rotations will return negative degrees, while counterclockwise rotations will return positive degrees. This measurement is takenwith respect to its start orientation. “Gyro.getRateMode()” returns the current angular velocity of the system in degrees-per-second. Once again, a clockwise motion will result in a negative angular velocity, while a counterclockwise motion will result in a positive angular velocity. Finally, ”Gyro.getAngleAndRateMode()” is a method that combines both the angle mode and the rate mode. The first two modes may seem redundant, but testing shows that it operates at almost the exact same speed as either of the individual measurements. In extremely time-sensitive situations it will likely prove extremely beneficial to have a means of avoiding any unwanted operations.
Each of these three methods sets the sensor to the appropriate mode. To actually obtain a reading, you must declare an array of long numbers and pass it as a parameter to the "fetch sample" method of the sample provider the methods create. For example:
float[] AngleSamples = newfloat[2];
. . .
Gyro.getAngleMode().fetchSample(AngleSamples, 0);
The fetch sample method returns its readings based on exactly one reading in the case of the Gyro Sensor. This is dangerous, given that any given reading can potentially be three degrees off. However, the relatively high sample rate (rate at which the sensor can take readings) of 1 KHz suggests that readings can be gathered quickly, so it may be wise to have the scanner take multiple readings and simply pass the average of them to other functions in the program. The sample code I’ve designed to go along with this guide demonstrates this, as it is able to accumulate 1000 readings, far more than you would need to ensure accuracy, in roughly 5 seconds.
Calibrating the Gyro Sensor is incredibly simple. There is a void method called “Gyro.reset()” which, as the name implies, resets the position and angular velocity of the sensor to zero. This method should probably be used at the beginning of any operation involving the Gyro Sensor, to absolutely ensure that no faulty readings will be lingering in the Sensor before readings begin. It should be noted that the Gyro Sensor must remain completely motionless while the recalibration is taking place.
A Sample Program
packageGyro_Tester;
import lejos.hardware.sensor.EV3GyroSensor;
importlejos.hardware.port.SensorPort;
importlejos.hardware.lcd.*;
importlejos.utility.Delay;
publicclassGyro_Tester {
publicstaticvoid main(String[] args) throwsInterruptedException {
EV3GyroSensor Gyro = new EV3GyroSensor(SensorPort.S1);
Gyro.reset();
LCD.drawString("Sample size = "+Gyro.sampleSize(), 0, 2);
Delay.msDelay(2000);
LCD.clear();
longstartTime;
long result = 0;
float[] AngleSamples = newfloat[2];
float[] RateSamples = newfloat[2];
float[] AngleRateSamples = newfloat[2];
Delay.msDelay(2000);
//Get the Angle.
for(inti = 0; i < 1000; i = i + 1){
startTime = System.currentTimeMillis();
Gyro.getAngleMode().fetchSample(AngleSamples, 0);
LCD.drawString("Angle = ", 0, 2);
LCD.drawString("= " + AngleSamples[0], 0, 3);
Delay.msDelay(10);
result = result + System.currentTimeMillis() - startTime - 10;
}
LCD.drawString("Average run time", 0, 5);
LCD.drawString("= "+(result / 1000), 0, 6);
Delay.msDelay(2000);
LCD.clear();
Delay.msDelay(2000);
//During the wait, begin manually changing the position of the
//Gyro Sensor.
//Get the Angular Velocity.
result = 0;
for(inti = 0; i < 1000; i = i + 1){
startTime = System.currentTimeMillis();
Gyro.getRateMode().fetchSample(RateSamples, 0);
LCD.drawString("Anglular Velocity", 0, 2);
LCD.drawString("= " + RateSamples[0], 0, 3);
Delay.msDelay(10);
result = result + System.currentTimeMillis() - startTime - 10;
}
LCD.drawString("Average run time", 0, 5);
LCD.drawString("= " + (result / 1000), 0, 6);
Delay.msDelay(2000);
LCD.clear();
Delay.msDelay(2000);
//Get both.
result = 0;
for(inti = 0; i < 1000; i = i + 1){
startTime = System.currentTimeMillis();
Gyro.getAngleAndRateMode().fetchSample(AngleRateSamples, 0);
LCD.drawString("Both", 0, 2);
LCD.drawString("= " + AngleRateSamples[0]+ ", "+
AngleRateSamples[1], 0, 3);
Delay.msDelay(10);
result = result + System.currentTimeMillis() - startTime - 10;
}
LCD.drawString("Average run time", 0, 5);
LCD.drawString("= " + (result / 1000), 0, 6);
Delay.msDelay(2000); //Let the last message display before ending the program.
}
}
Sources:
Lejos EV3 API:
Explanation of a Gyro Sensor:
Explanation of a Gyroscope in general:
Blog Post focusing on The Gyro Sensor in EV3:
Information on UART ports:
Hardware specifications on the GyroSensor: