All pages
Powered by GitBook
1 of 3

Loading...

Loading...

Loading...

Programming Color Sensors

It is recommended to create a new OpMode while following this tutorial. Ours is named HelloRobot_ColorSensor!

Color Sensor Basics:

While a touch sensor features a physical switch to gather information, a color sensor makes use of reflected light. By doing so it collects different data to determine how much light it is seeing, the distance to a surface, and of course what color is in front of it.

But what makes up a color?

For our robot we're going to focus on a few key components: hue, saturation, and value. With these we can use something known as the HSV color model to have the robot translate what its seeing into a recognizable color.

HSV is a form of a cylindrical RGB color model used to do things like create color pickers for digital painting programs, to edit photos, and for programming vision code.

Hue, saturation, and value all will play a part in helping our robot tell us what color it detects and allow us to make adjustments for something like a uniquely colored game piece!

Detecting Light vs. Dark

Before we tackle colors, let's start with having our robot use the color sensor to tell us how much light is being reflected.

To do this we need to ask our color sensor to act as a light sensor, specifically an OpticalDistanceSensor.

 while (opModeIsActive()) {
            telemetry.addData("Light Detected", ((OpticalDistanceSensor) test_color).getLightDetected());
            telemetry.update();
   }

For this use case, we will use getLightDetected() to have the sensor report the amount of light detected in a range of 0-1.

Time to test your program to see what your color sensor detects! While testing think about the following questions:

  • Is the number higher when less or more light is detected?

  • What happens when the color sensor looks at different color surfaces?

  • Does the value change when turning the color sensor's LED light on or off?

  • Does the value change if there is a shadow or if the lighting in the room changes?

When using the option to "" while creating a new OpMode, the color sensor will be established similar to the following:

However, for this tutorial we want to set our color sensor up as a NormalizedColorSensor.

Color Normalization is another technique within vision programming intended to help compensate for differences caused by lighting and shadows when looking at colors. This also affects shades of a color. For example, there are a ton of different shades of blue, such as cyan, navy, and aquamarine, but to our robot these will all be referenced as blue.

With our color sensor now set for normalized colors, we'll add a call for NormalizedRGBA colors before we add telemetry for each individually.

Now we're ready to collect more data from our color sensor!

Quick Check!

What happened?

Likely, the numbers and differences you saw while testing are different than those we'd see ourselves. There are many factors that might change the color sensor's readings including the lighting in the room and surface material.

However, one thing that is the same is that 1 should be the least amount of light, such as when your hand is covering the sensor, and 0 is the most amount of light being seen.

Normalized Colors

Setup Code for Configured Hardware
public class HelloRobot_ColorSensor extends LinearOpMode {
    private ColorSensor test_color;

    @Override
    public void runOpMode() {
        test_color = hardwareMap.get(ColorSensor.class, "test_color");
public class HelloRobot_ColorSensor extends LinearOpMode {
    private NormalizedColorSensor test_color;
    
    @Override
    public void runOpMode() {
        test_color = hardwareMap.get(NormalizedColorSensor.class, "test_color");
while (opModeIsActive()) {
            telemetry.addData("Light Detected", ((OpticalDistanceSensor) test_color).getLightDetected());
            
            NormalizedRGBA colors = test_color.getNormalizedColors(); 
            telemetry.update();
        }

Color Sensor Telemetry

We are going to add several telemetry sections within our program, but let's start by having our robot tell us how much red, green, or blue it sees when looking at an object with our Color Sensor.

telemetry.addData("Red", "%.3f", colors.red);
telemetry.addData("Green", "%.3f", colors.green);
telemetry.addData("Blue", "%.3f", colors.blue);

For each telemetry line we are specifying first the label to be displayed on the Driver Hub's screen, "Red", "Green", or "Blue". Then we are setting our output to only be 3 decimal places using "%.3f".

Finally we ask the color sensor to report the amount seen of each color using colors.red, colors.green, or colors.blue.

Adding Hue, Saturation, and Value Telemetry

To add telemetry for hue, saturation, and value we will be using the class JavaUtil and matching method for the information we wish to add: colorToHue, colorToSaturation, or colorToValue.

Because we are using NormalizedRGBA for our class of normalized color values, we need to take an extra step to be able to collect HSV components. By calling toColor() we are converting from a "FTC SDK RGBA Color Object" to an "Android HSV Color Object".

Similarly to our individual colors, we use "%.3f" to show 3 decimal places for the value reported. While we can add this to Hue as well, this value should report as a much larger whole number. We'll look at this more closely in the next section!

Save your OpMode and give it a try! How do the values change depending on what color object the sensor is looking at?

While working on your code, you may have noticed something called "alpha". The alpha value of a surface tells how transparent or opaque it may be.

Using a similar method as before, we can add a telemetry call for the alpha value to see on our Driver Hub.

Here is how our OnBot Java code should look after setting up our color sensor to collect all the information!

Detecting Color

We've asked our robot to gather a lot of data with the color sensor. Now let's have it use that information to output an actual color name rather than just a value!

To determine the final color we will be using the reported hue value from JavaUtil.colorToHue(colors.toColor()). Because we'll be using hue repeatedly, let's establish it as a variable to help keep our code clean.

First we will set up "hue" as a number data type during initialization:

Next, we'll define "hue" while our opModeIsActive using the same method as before:

With our variable added, our current code should appear as follows:

Recall when we learned about using

Quick Check!

This feature requires the Color Sensor's LED to be switched on!

Alpha Telemetry

Code Checkpoint

Let's first set up the skeleton of our if/else statement for determining different colors:

Each check will be for a certain color that is within the specified range. For example, a color that's hue is between 90-149 should appear as green.

Within each statement let's add a telemetry.addData and the color for that range:

The exact hue values may need to be adjusted slightly, but those used above are based on the default conversion of HSV to RGB when using hue to identify color.

You'll notice that "red" is detected for values under 30 and above 350. This is intentional as red is the beginning and end of the RGB spectrum!

Build your OpMode and give it a try! You can adjust the values as you need to better reflect the colors available or changes due to lighting in the room.

Adding a Hue Variable

Detecting Common Colors

if/else statements while working with the touch sensor.

Full Color Sensor Program

telemetry.addData("Hue", JavaUtil.colorToHue(colors.toColor()));
telemetry.addData("Saturation", "%.3f", JavaUtil.colorToSaturation(colors.toColor()));
telemetry.addData("Value", "%.3f", JavaUtil.colorToValue(colors.toColor()));
telemetry.addData("Alpha", "%.3f", colors.alpha);
@TeleOp
public class HelloRobot_ColorSensor extends LinearOpMode {
    private NormalizedColorSensor test_color;
    
    @Override
    public void runOpMode() {
        test_color = hardwareMap.get(NormalizedColorSensor.class, "test_color");

        waitForStart();

        while (opModeIsActive()) {
            telemetry.addData("Light Detected", ((OpticalDistanceSensor) test_color).getLightDetected());
            NormalizedRGBA colors = test_color.getNormalizedColors();
    
    //Determining the amount of red, green, and blue
            telemetry.addData("Red", "%.3f", colors.red);
            telemetry.addData("Green", "%.3f", colors.green);
            telemetry.addData("Blue", "%.3f", colors.blue);
     
     //Determining HSV and alpha 
            telemetry.addData("Hue", JavaUtil.colorToHue(colors.toColor()));
            telemetry.addData("Saturation", "%.3f", JavaUtil.colorToSaturation(colors.toColor()));
            telemetry.addData("Value", "%.3f", JavaUtil.colorToValue(colors.toColor()));
            telemetry.addData("Alpha", "%.3f", colors.alpha);
            telemetry.update();
        }
    }
}
@TeleOp
public class HelloRobot_ColorSensor extends LinearOpMode {
    private NormalizedColorSensor test_color;
    double hue; // <------ New code
while (opModeIsActive()) {
            telemetry.addData("Light Detected", ((OpticalDistanceSensor) test_color).getLightDetected());
            NormalizedRGBA colors = test_color.getNormalizedColors();
            hue = JavaUtil.colorToHue(colors.toColor()); // <------ New code
@TeleOp
public class HelloRobot_ColorSensor extends LinearOpMode {
    private NormalizedColorSensor test_color;
    double hue; // <------ New code
    
    @Override
    public void runOpMode() {
        test_color = hardwareMap.get(NormalizedColorSensor.class, "test_color");
​
        waitForStart();
​
        while (opModeIsActive()) {
            telemetry.addData("Light Detected", ((OpticalDistanceSensor) test_color).getLightDetected());
            NormalizedRGBA colors = test_color.getNormalizedColors();
            hue = JavaUtil.colorToHue(colors.toColor()); // <------ New code
    
    //Determining the amount of red, green, and blue
            telemetry.addData("Red", "%.3f", colors.red);
            telemetry.addData("Green", "%.3f", colors.green);
            telemetry.addData("Blue", "%.3f", colors.blue);
     
     //Determining HSV and alpha 
            telemetry.addData("Hue", JavaUtil.colorToHue(colors.toColor()));
            telemetry.addData("Saturation", "%.3f", JavaUtil.colorToSaturation(colors.toColor()));
            telemetry.addData("Value", "%.3f", JavaUtil.colorToValue(colors.toColor()));
            telemetry.addData("Alpha", "%.3f", colors.alpha);
            telemetry.update();
        }
    }
}
if(hue < 30){
          
  }
  else if (hue < 60) {
          
  }
  else if (hue < 90){
          
  }
  else if (hue < 150){
          
  }
  else if (hue < 225){
          
  }
  else if (hue < 350){
          
  }
  else{
          
      }
 if(hue < 30){
          telemetry.addData("Color", "Red");
  }
  else if (hue < 60) {
          telemetry.addData("Color", "Orange");
  }
  else if (hue < 90){
          telemetry.addData("Color", "Yellow");
  }
  else if (hue < 150){
          telemetry.addData("Color", "Green");
  }
  else if (hue < 225){
          telemetry.addData("Color", "Blue");
  }
  else if (hue < 350){
          telemetry.addData("Color", "Purple");
  }
  else{
          telemetry.addData("Color", "Red");
  }
@TeleOp
public class HelloRobot_ColorSensor extends LinearOpMode {
    private NormalizedColorSensor test_color;
    double hue; 
    
    @Override
    public void runOpMode() {
        test_color = hardwareMap.get(NormalizedColorSensor.class, "test_color");
        
        waitForStart();
        
        while (opModeIsActive()) {
            telemetry.addData("Light Detected", ((OpticalDistanceSensor) test_color).getLightDetected());
            NormalizedRGBA colors = test_color.getNormalizedColors();
            hue = JavaUtil.colorToHue(colors.toColor()); 
    
    //Determining the amount of red, green, and blue
            telemetry.addData("Red", "%.3f", colors.red);
            telemetry.addData("Green", "%.3f", colors.green);
            telemetry.addData("Blue", "%.3f", colors.blue);
     
     //Determining HSV and alpha 
            telemetry.addData("Hue", JavaUtil.colorToHue(colors.toColor()));
            telemetry.addData("Saturation", "%.3f", JavaUtil.colorToSaturation(colors.toColor()));
            telemetry.addData("Value", "%.3f", JavaUtil.colorToValue(colors.toColor()));
            telemetry.addData("Alpha", "%.3f", colors.alpha);
       
       //Using hue to detect color
         if(hue < 30){
                 telemetry.addData("Color", "Red");
                 }
          else if (hue < 60) {
                 telemetry.addData("Color", "Orange");
                 }
          else if (hue < 90){
                 telemetry.addData("Color", "Yellow");
                }
          else if (hue < 150){
                 telemetry.addData("Color", "Green");
                }
          else if (hue < 225){
                 telemetry.addData("Color", "Blue");
                }
          else if (hue < 350){
                 telemetry.addData("Color", "Purple");
                }
          else{
                 telemetry.addData("Color", "Red");
                }
            telemetry.update();
        }
    }
}