main.c
来自「一个机器人开发的相关嵌入式开发源码」· C语言 代码 · 共 1,936 行 · 第 1/4 页
C
1,936 行
uart0SendString((unsigned char *)"##");
uart0SendString((unsigned char *)svfr);
uart0SendChar((unsigned char)(jpegsize & 0xFF));
uart0SendChar((unsigned char)((jpegsize/256) & 0xFF));
uart0SendChar(0x00);
uart0SendChar(0x00);
for (jx=0; jx<(jpegsize/100)+1; jx++) {
for (ix=(jx*100); (ix<((jx*100)+100)) && (ix<jpegsize); ix++)
uart0SendChar(c328_buf[ix]);
delayUs(1000);
}
break;
case 'w': // turn on "wander mode"
decode_jpeg = TRUE;
init_wander = 1;
wander_motor = 1;
uart0SendString((unsigned char *)"#w");
break;
case 'W': // turn off "wander mode"
lspeed = 0;
rspeed = 0;
wander_motor = 0;
//decode_jpeg = FALSE;
uart0SendString((unsigned char *)"#W");
break;
case 'm': // turn on "wander mode", but disable autonomous wandering
lspeed = 0;
rspeed = 0;
decode_jpeg = TRUE;
init_wander = 1;
wander_motor = 0;
uart0SendString((unsigned char *)"#m");
break;
case 'M': // grab 3 character motor command string (left, right, delay)
lspeed = (int)((signed char)uart0GetCh());
rspeed = (int)((signed char)uart0GetCh());
delay = (unsigned int)uart0GetCh();
setPwmDutyPercent(lspeed, rspeed);
if (delay) {
delayUs(delay * 10000);
setPwmDutyPercent(0, 0);
lspeed = 0;
rspeed = 0;
}
uart0SendString((unsigned char *)"#M");
break;
case '+': // increase base motor speed
base_speed += 5; if (base_speed > 75) base_speed = 75;
uart0SendString((unsigned char *)"#+");
break;
case '-': // decrease base motor speed
base_speed -= 5; if (base_speed < 35) base_speed = 35;
uart0SendString((unsigned char *)"#-");
break;
case 'a':
decode_jpeg = FALSE; // no wander mode for IMJ1
if (!camera_set_resolution('1'))
goto restart;
svfr[3] = '1';
uart0SendString((unsigned char *)"#a");
break;
case 'b':
if (!camera_set_resolution('3'))
goto restart;
svfr[3] = '3';
uart0SendString((unsigned char *)"#b");
break;
case 'c':
decode_jpeg = FALSE; // no wander mode for IMJ5
if (!camera_set_resolution('5'))
goto restart;
svfr[3] = '5';
uart0SendString((unsigned char *)"#c");
break;
case '7': // drift left
case '8': // forward
case '9': // drift right
case '4': // turn left
case '5': // stop
case '6': // turn right
case '1': // back left
case '2': // back
case '3': // back right
case '0': // counter clockwise turn
case '.': // clockwise turn
set_motor(rxChar, base_speed, &lspeed, &rspeed); uart0SendChar('#'); uart0SendChar(rxChar);
break;
default:
break;
}
breakout:
// setPwmDutyPercent(0, 0);
while (uart0GetChar(&rxChar)) // do we need to stop motors briefly while flushing recv buffer ?
continue;
}
if ((failsafe) && ((TIMER0_TC - t1) > 1000)) // if failsafe enabled, turn off motors if no signal
setPwmDutyPercent(0, 0); // has been received for 1 sec
else
setPwmDutyPercent(lspeed, rspeed);
if (xmit_beacon) { // if "xmit beacon" mode on, send 0xFF minus id
ch = 255 - (unsigned char)id; // so if id=1, xmit char is 0xFE
bounceIR(FORWARD, ch);
bounceIR(LEFT, ch);
bounceIR(BACK, ch);
bounceIR(RIGHT, ch);
}
jpegsize = camera_grab_frame(c328_buf);
switch (jpegsize) {
case RESTART:
goto restart;
case RETRY:
if (++retry_count > 6)
goto restart;
continue;
}
retry_count = 0;
framecount++;
if (decode_jpeg == FALSE) // just hold the captured jpeg, but don't decompress
continue;
// if decode_jpeg is true, then decompress and dump Y pixels
if ((c328_buf[0] != 0xFF) || (c328_buf[1] != 0xD8))
continue;
switch (svfr[3]) {
case '1': // don't decode IMR1, IMR5 or IMR7
case '5':
case '7':
continue;
case '3':
ix = 160;
iy = 128;
break;
}
JPEG_DecompressImage(c328_buf, decode_buf, ix, iy);
if (init_wander) { // hardcoded for IMJ3 80x64 YUV
init_wander = 0;
vgrab(0, 20, 59, 0, 5); // sets ymax[0], ymin[0], umax[0], umin[0], vmax[0], vmin[0]
}
vscan(0);
for (ix=0; ix<7; ix++) { // in groups of 20 columns, compute max, mean and # of zeros
tmax[ix] = tmean[ix] = tzeros[ix] = 0;
for (jx=0; jx<20; jx++) {
itmp = tvect[(ix*10) + jx];
if (tmax[ix] < itmp)
tmax[ix] = itmp;
tmean[ix] += itmp;
if (itmp == 0)
tzeros[ix]++;
}
tmean[ix] /= 20;
}
tflag = 0; // flag the 7 open/blocked regions, and pack the flags into a single 7-bit word
for (ix=0; ix<7; ix++) // a table lookup (motor_cmd[]) is used to set robot action
if (tzeros[ix] <8)
tflag += (0x40 >> ix);
if (locate_beacon) { // lower 11 bits of listenIR returns 2 start bits, 8 data bits, 1 stop bit
ix = listenIR(100);
//printNumber(16, 8, FALSE, '0', ix);
nforward = (ix >> 28) & 0x0000000F;
nleft = (ix >> 24) & 0x0000000F;
nback = (ix >> 20) & 0x0000000F;
nright = (ix >> 16) & 0x0000000F;
if ((nleft > nforward) && (nleft > nback) && (nleft > nright)) {
set_motor('0', base_speed, &lspeed, &rspeed); // turn left
continue;
}
else if ((nright > nforward) && (nright > nleft) && (nright > nback)) {
set_motor('.', base_speed, &lspeed, &rspeed); // turn right
continue;
}
else if ((nback > nforward) && (nback > nright) && (nback > nleft)) {
set_motor('0', base_speed, &lspeed, &rspeed); // turn left
continue;
}
}
if (wander_motor)
set_motor(motor_cmd[tflag], base_speed, &lspeed, &rspeed);
}
}
void vgrab(unsigned int ii, unsigned int x1, unsigned int x2, unsigned int y1, unsigned int y2) {
unsigned int xx, yy, y, u, v;
ymax[ii] = 0;
ymin[ii] = 255;
umax[ii] = 0;
umin[ii] = 255;
vmax[ii] = 0;
vmin[ii] = 255;
for (yy=y1; yy<=y2; yy++) {
for (xx=x1; xx<=x2; xx++) {
y = (unsigned int)decode_buf[index(xx,yy)];
u = (unsigned int)decode_buf[index(xx,yy)+5120];
v = (unsigned int)decode_buf[index(xx,yy)+10240];
if (ymax[ii] < y)
ymax[ii] = y;
if (ymin[ii] > y)
ymin[ii] = y;
if (umax[ii] < u)
umax[ii] = u;
if (umin[ii] > u)
umin[ii] = u;
if (vmax[ii] < v)
vmax[ii] = v;
if (vmin[ii] > v)
vmin[ii] = v;
}
}
}
void vscan(unsigned int ii) {
unsigned int xx, yy, y, u, v;
for (xx=0; xx<80; xx++) { // for each column, measure distance to first mismatch from initial samples
tvect[xx] = 64; // max distance will be 64 pixels (height of image)
for (yy=0; yy<64; yy++) {
y = (unsigned int)decode_buf[index(xx,yy)];
u = (unsigned int)decode_buf[index(xx,yy)+5120];
v = (unsigned int)decode_buf[index(xx,yy)+10240];
if ((y < ymin[ii])
|| (y > ymax[ii])
|| (u < umin[ii])
|| (u > umax[ii])
|| (v < vmin[ii])
|| (v > vmax[ii])) {
tvect[xx] = yy;
break;
}
}
}
}
void vblob(unsigned int ii) {
unsigned int xx, yy, y, u, v, jj, count, bottom, top, tmp;
for (jj=0; jj<MAX_BLOBS; jj++) {
blobcnt[jj] = 0;
blobx1[jj] = 80;
blobx2[jj] = 0;
bloby1[jj] = 64;
bloby2[jj] = 0;
}
jj = 0; // jj indicates the current blob being processed
for (xx=0; xx<80; xx++) {
count = 0;
bottom = 64;
top = 0;
for (yy=0; yy<64; yy++) {
y = (unsigned int)decode_buf[index(xx,yy)];
u = (unsigned int)decode_buf[index(xx,yy)+5120];
v = (unsigned int)decode_buf[index(xx,yy)+10240];
if ((y >= ymin[ii])
&& (y <= ymax[ii])
&& (u >= umin[ii])
&& (u <= umax[ii])
&& (v >= vmin[ii])
&& (v <= vmax[ii])) {
count++;
if (bottom > yy)
bottom = yy;
if (top < yy)
top = yy;
}
}
if (count) {
if (bloby1[jj] > bottom)
bloby1[jj] = bottom;
if (bloby2[jj] < top)
bloby2[jj] = top;
if (blobx1[jj] > xx)
blobx1[jj] = xx;
if (blobx2[jj] < xx)
blobx2[jj] = xx;
blobcnt[jj] += count;
} else {
if (blobcnt[jj]) // move to next blob if a gap is found
jj++;
if (jj > (MAX_BLOBS-1))
goto blobbreak;
}
}
blobbreak: // now sort blobs by size, largest to smallest pixel count
for (xx=0; xx<=jj; xx++) {
if (blobcnt[xx] == 0) // no more blobs, so exit
return;
for (yy=xx; yy<=jj; yy++) {
if (blobcnt[yy] == 0)
break;
if (blobcnt[xx] < blobcnt[yy]) {
tmp = blobcnt[xx];
blobcnt[xx] = blobcnt[yy];
blobcnt[yy] = tmp;
tmp = blobx1[xx];
blobx1[xx] = blobx1[yy];
blobx1[yy] = tmp;
tmp = blobx2[xx];
blobx2[xx] = blobx2[yy];
blobx2[yy] = tmp;
tmp = bloby1[xx];
bloby1[xx] = bloby1[yy];
bloby1[yy] = tmp;
tmp = bloby2[xx];
bloby2[xx] = bloby2[yy];
bloby2[yy] = tmp;
}
}
}
}
void set_motor(unsigned char ch, int speed, int *ls, int *rs) { int left_speed, right_speed;
left_speed = right_speed = 0; switch (ch) { case '7': // drift left
left_speed = speed-10;
right_speed = speed+10;
break;
case '8': // forward
left_speed = speed;
right_speed = speed;
break;
case '9': // drift right
left_speed = speed+10;
right_speed = speed-10;
break;
case '4': // turn left
left_speed = speed-20;
right_speed = speed+20;
break;
case '5': // stop
left_speed = 0;
right_speed = 0;
break;
case '6': // turn right
left_speed = speed+20;
right_speed = speed-20;
break;
case '1': // back left
left_speed = -(speed-20);
right_speed = -(speed+20);
break;
case '2': // back
left_speed = -speed;
right_speed = -speed;
break;
case '3': // back right
left_speed = -(speed+20);
right_speed = -(speed-20);
break;
case '0': // counter clockwise turn
setPwmDutyPercent(-speed, speed);
delayUs(200000);
setPwmDutyPercent(0, 0);
left_speed = 0;
right_speed = 0;
break;
case '.': // clockwise turn
setPwmDutyPercent(speed, -speed);
delayUs(200000);
setPwmDutyPercent(0, 0);
left_speed = 0;
right_speed = 0;
break; } setPwmDutyPercent(left_speed, right_speed);
*ls = left_speed;
*rs = right_speed;
return;
}
#ifdef _BASIC_
#define NUM_LAB 100
#define LAB_LEN 10
#define FOR_NEST 25
#define SUB_NEST 25
#define DELIMITER 1
#define VARIABLE 2
#define NUMBER 3
#define COMMAND 4
#define STRING 5
#define QUOTE 6
#define PRINT 1
#define INPUT 2
#define IF 3
#define THEN 4
#define FOR 5
#define NEXT 6
#define TO 7
#define GOTO 8
#define EOL 9
#define FINISHED 10
#define GOSUB 11
#define RETURN 12
#define COMMENT 13
#define TIME 14
#define MOTORS 15
#define DELAY 16
#define IR 17
#define IMGCAP 18
#define COLORCAP 19
#define COLORSET 20
#define COLORGET 21
#define SCAN 22
#define BLOB 23
#define BITDIR 24
#define BITSET 25
#define BITGET 26
#define END 27
jmp_buf e_buf; /* hold environment for longjmp() */
struct cmds { /* keyword lookup table */
char command[20];
char tok;
} ccmd[] = {
{"print", PRINT},
{"input", INPUT},
{"if", IF},
{"then", THEN},
{"goto", GOTO},
{"for", FOR},
{"next", NEXT},
{"to", TO},
{"gosub", GOSUB},
{"return", RETURN},
{"time", TIME},
{"motors", MOTORS},
{"delay", DELAY},
{"ir", IR},
{"imgcap", IMGCAP},
{"colorcap", COLORCAP},
{"colorset", COLORSET},
{"colorget", COLORGET},
{"scan", SCAN},
{"blob", BLOB},
{"bitdir", BITDIR},
{"bitset", BITSET},
{"bitget", BITGET},
{"comment", COMMENT},
{"end", END},
{"", END}
};
int vvar[26]= { /* 26 user variables, A-Z */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0
};
char token[80];
char token_type, tok;
struct label {
char name[LAB_LEN];
char *p; /* points to place to go in source file*/
};
struct label label_ccmd[NUM_LAB];
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?