<< return to Pixycam.com

Object Clearing Robot

Hello All,

I am trying to build an autonomous robot for a competition in which the aim is to knock over a series of orange batons on the floor.

I have made a start with an arduino colour following robot, (please see http://tutorial.cytron.com.my/2015/08/28/colour-tracking-mobile-robot-pixy/), which will track and follow a single colour. However, there are a number of batons to track and then knock over, so I am trying to create a priority for the robot to pick one ‘block’, knock it over, then move on to the next.

If the batons were all different colours then I could move through the signatures in order using “else if”, but instead they are all orange.

Is there a way to map different blocks of the same colour onto signatures, or to use an equivalent of “if(signature == 1)” for blocks?

I would greatly appreciate any help here.

Thanks,

Adair

The code is below :

//Pixy arduino robot
//Arduino IDE 1.6.4

#include <SPI.h>
#include <Pixy.h>

Pixy pixy;

int signature = 0;
int x = 0; //positon x axis
int y = 0; //position y axis
unsigned int width = 0; //object’s width
unsigned int height = 0; //object’s height
unsigned int area = 0;
unsigned int newarea = 0;
int Xmin = 70; //min x position
int Xmax = 200; //max x position
int maxArea = 0;
int minArea = 0;
int motor1 = 3; //motor1 on Pin 3
int enable1 = 4; //direction1 on Pin 4
int motor2 = 9; //motor2 on Pin 9
int enable2 = 12; //direction2 on Pin 12
int Speed = 10; //speed for motor
static int i = 0;

void setup()
{
pinMode(motor1, OUTPUT);
pinMode(motor2, OUTPUT);
pinMode(enable1, OUTPUT);
pinMode(enable2, OUTPUT);
Serial.begin(9600);
Stop();
pixy.init();
}

void loop()
{
while(millis()<10000)
{
scan();
area = width * height; //calculate the object area
maxArea = area + 1000;
minArea = area - 1000;
}

scan(); 

if(signature == 1)//looking for signature 1
{

newarea = width * height; //calculate the object area

  if (x < Xmin)//turn left if x position < max x position
  {     
   left();
  }
  else if (x > Xmax) //turn right if x position > max x position
  {
   right();
  }
  else if(newarea < minArea)//go forward if object too small
  {
   forward(); 
  }
  else if(newarea > maxArea)//go backward if object too big
  {
   backward(); 
  }
  
  //else stop
  else
  {
    Stop(); 
  } 

}
else
{
Stop();
}
}

void backward()//backward
{
digitalWrite(motor1, LOW);
digitalWrite(motor2, LOW);
analogWrite(enable1, Speed);
analogWrite(enable2, Speed);
}

void forward()//forward
{
digitalWrite(motor1, HIGH);
digitalWrite(motor2, HIGH);
analogWrite(enable1, Speed);
analogWrite(enable2, Speed);
}

void right()//turn right
{
digitalWrite(motor1, HIGH);
digitalWrite(motor2, LOW);
analogWrite(enable1, Speed);
analogWrite(enable2, Speed);
}

void left()//turn left
{
digitalWrite(motor1, LOW);
digitalWrite(motor2, HIGH);
analogWrite(enable1, Speed);
analogWrite(enable2, Speed);
}

void Stop()//stop
{
digitalWrite(enable1, LOW);
digitalWrite(enable2, LOW);
}
void scan()
{
uint16_t blocks;
blocks = pixy.getBlocks(); //receive data from pixy
signature = pixy.blocks[i].signature; //get object’s signature
x = pixy.blocks[i].x; //get x position
y = pixy.blocks[i].y; //get y position
width = pixy.blocks[i].width; //get width
height = pixy.blocks[i].height; //get height
}

Hello Adair,
I’m having trouble understanding your code. Usually, the index (i) for the array pixy.blocks[i] is managed, incremented by a for loop. See the hello world code here:

This way you can increment through all of the blocks and determine which ones are interesting, higher priority.

One idea is to prioritize batons that appear lower in the image (ie, have a higher y value). These are the ones that will be closer to the robot.

Hope this helps!

Edward

Hi Edward,

Thank you so much for your help! I have now added a for loop to the code which looks through the index for the biggest block. The biggest block is then assigned as pixy.block[j] and the x y values can be obtained.

With best wishes,

Adair