#include "system.h"
#include "pid.h"
#include "math.h"
/* Pixy Library functions (start) */
#define PIXY_ARRAYSIZE 30
#define PIXY_START_WORD 0xaa55
#define PIXY_START_WORD_CC 0xaa56
#define PIXY_START_WORDX 0x55aa
typedef struct {
unsigned short signature;
unsigned short x;
unsigned short y;
unsigned short width;
unsigned short height;
unsigned short angle;
} Block;
typedef enum BlockType {
NORMAL_BLOCK,
CC_BLOCK
} BlockType;
Block blocks[PIXY_ARRAYSIZE];
BlockType blockType;
short skipStart;
short getStart() {
unsigned short w, lastw = 0xffff;
char c;
while(ReceiveBuffer(&w, 2, 100) == 2) {
if (w==PIXY_START_WORD && lastw==PIXY_START_WORD) {
blockType = NORMAL_BLOCK;
return 1;
}
else if (w==PIXY_START_WORD_CC && lastw==PIXY_START_WORD) {
blockType = CC_BLOCK;
return 1;
}
else if (w==PIXY_START_WORDX) {
ReceiveBuffer(&c, 1, 100);
}
lastw = w;
}
return 0;
}
short getBlocks(short maxBlocks) {
short bc;
short i;
unsigned short w, checksum, sum;
if (!skipStart) {
if (getStart()==0)
return 0;
}
skipStart = 0;
for (bc = 0; bc < maxBlocks && bc < PIXY_ARRAYSIZE;) {
ReceiveBuffer(&checksum, 2, 100);
if (checksum==PIXY_START_WORD) {
skipStart = 1;
blockType = NORMAL_BLOCK;
return bc;
}
else if (checksum==PIXY_START_WORD_CC) {
skipStart = 1;
blockType = CC_BLOCK;
return bc;
}
else if (checksum==0) {
return bc;
}
if (blockType == NORMAL_BLOCK) {
ReceiveBuffer(&blocks[bc],10,100);
blocks[bc].angle = 0;
}
else {
ReceiveBuffer(&blocks[bc],12,100);
}
sum = blocks[bc].signature;
sum += blocks[bc].x;
sum += blocks[bc].y;
sum += blocks[bc].width;
sum += blocks[bc].height;
sum += blocks[bc].angle;
if (checksum==sum)
bc++;
ReceiveBuffer(&w, 2, 100);
if (w==PIXY_START_WORD) {
blockType = NORMAL_BLOCK;
}
else if (w==PIXY_START_WORD_CC) {
blockType = CC_BLOCK;
}
else {
return bc;
}
}
return bc;
}
void setServos(short s0, short s1) {
short outBuf[3];
outBuf[0] = 0xff00;
outBuf[1] = s0;
outBuf[2] = s1;
SendBuffer(outBuf, 6);
}
/* Pixy Library functions (end) */
int main() {
float pan, tilt;
pid pid_pan, pid_tilt;
unsigned long oldtime;
ChangeBaud(19200);
// pid,p,i,d,iLim,CutOff
pid_configure(&pid_pan,0.1,0,0.02,100,20);
pid_configure(&pid_tilt,0.2,0,0.05,100,20);
pid_zero(&pid_pan);
pid_zero(&pid_tilt);
for (float a=0; a<10; a += 0.01) {
pan = 500 + 500.0*sin(a);
tilt = 500 + 500.0*cos(3*a);
setServos(pan,tilt);
delay(10);
}
setServos(500,500);
pan = 500;
tilt = 500;
oldtime = time();
for (unsigned long timeout = time() + 30000; timeout > time();) {
short block = getBlocks(1);
if (block) {
float dT = (time() - oldtime)/1000.0;
pan -= pid_apply(&pid_pan, blocks[0].x - 160, dT);
tilt += pid_apply(&pid_tilt, blocks[0].y - 100, dT);
pan = (pan < 100) ? 100 : ((pan > 900) ? 900 : pan);
tilt = (tilt < 100) ? 100 : ((tilt > 900) ? 900 : tilt);
setServos(pan,tilt);
oldtime = time();
TestValSet(pan);
}
}
setServos(500,500);
return 0;
}
exit(main());