Sorry guys, another question about rangefinding

This forum is used for discussing hardware, software, and technical details of the AVRcam embedded system.

Sorry guys, another question about rangefinding

Postby davedave » Sun Aug 13, 2006 8:48 pm

I want to use the brightest pixel method, we don't have the ram for a full dump of even just the red pixels so it has to be done as the lines are read.

I need to be able to do a check as the pixels are being read which means either 6 or 14 clock cycles (dumping or tracking mode, -2 cycles for loop), preferably 6 to allow full resolution. I'm thinking of storing a timer1 read as the location in register X and the value in register Z (if memory serves register Y is being used already). Even so, I'm having trouble thinking up how I can squeeze it in to the available cycles. Does anyone know how much time there is at the end of a line read before the next line starts? John has the chip sleeping, but that only guarantees 3 clock cycles. I need there to be enough time to offload my maximum value to an array and still send the chip to sleep (5 clocks).

By only looking at the red pixels I get a whole lot more time but even so it's going to be tight.
davedave
 
Posts: 15
Joined: Wed May 10, 2006 11:02 pm
Location: Canberra Australia

Postby Ringo » Tue Aug 15, 2006 2:22 pm

I'm trying to do the same thing. I was planning on doing it like the DF command. If reads all the data from the camera then sends it out the port later. I was planning on doing the compares at the point where it is sending serial data and then only sending the highest value. I think I'll start by Turning the camera sideways and looking at a row. Right now I'm trying to write a c# app to display the byr data on my screen. Once I get that working I can easily convert it to show my new brightest pixel data. Please post if you get it working.
Ringo
Ringo
 
Posts: 19
Joined: Thu Jun 23, 2005 9:48 am

Postby davedave » Thu Aug 24, 2006 10:04 pm

Yup, modified the screen dump event to only spit out the brightest pixel and displaying the results in matlab. The result is poor at the moment so I'll be implementing a software low pass filter (average) on the data between rows (columns with the camera on its side).

So the modfied code: Receive 'EF' over serial then
1. get dump line
2. pick off red pixels
3. run 3 point averager
4. pick off brightest pixel
5. send brightest pixel over serial
6. repeat till finished

3 and 4 run in one pass, hopefully 2,3,4 in one pass once I get some time.

Here's my modifications and shamless rip off of Johns code with some matlab code including sample data. I haven't put the averager/filter in yet. It should appear as almost a straight line, but obviously doesn't.

function ans = goodData()
% cam holds uncalibrated hexadecimal range data from AVRcam. First byte
% seems to always be bad

% cam2 is similar, but more carefully set up to have a chance at seeing
% side to side
cam = '01 69 69 69 69 69 69 69 69 69 69 67 67 87 87 87 89 67 67 67 67 67 67 65 67 65 65 65 65 65 41 65 65 65 65 65 65 65 65 65 65 65 65 65 63 63 63 63 63 63 63 73 03 05 4D 07 25 07 05 43 73 03 5F 03 2D 09 01 1F 55 01 05 2D';
cam2 = '01 01 01 01 57 43 57 57 57 57 55 55 55 55 55 55 55 55 55 55 55 55 49 55 53 55 03 55 55 53 55 55 55 53 53 53 53 53 53 53 53 53 53 53 51 51 43 51 51 01 23 17 15 51 51 51 4F 51 51 53 53 53 53 1B 2F 51 51 51 4F 4F 4F 4F';
hold on;
m=0;
for n=1:3:(length(cam)-1)
m = m+1;
camN(m)=hex2dec([cam(n),cam(n+1)]);
end
plot(camN,'g');
m=0;
for n=1:3:(length(cam2)-1)
m = m+1;
camN(m)=hex2dec([cam2(n),cam2(n+1)]);
end
plot(camN,'r');
hold off;



Modifications to AVRcam:
Added rangefinding event.
In frameMgr_aquireLine():
if ((currentState == ST_FrameMgr_DumpingFrame)||( currentState == ST_FrameMgr_RF))


In frameMgr_processLine():
else if (currentState == ST_FrameMgr_RF)
{
unsigned char count =0;
unsigned char max =0;
unsigned char place =0;
unsigned char count1 =0;
unsigned char max1 =0;
unsigned char place1 =0;
volatile unsigned char dataToSend1;

/* pick off the largest red value then send it through serial followed
by byte containing magnitude and number of counts at that level (max = 16) */

/* currentLineBuffer is getting "g" previousLineBuffer is getting "b-r" */
//UartInt_txByte(0x0B); /* send the header byte */
//UartInt_txByte(lineCount); /* send the line count */
for (i=0; i<NUM_PIXELS_IN_A_DUMP_LINE; i+=2)
{
/* *previousLineBuffer contains red and blue data*/

place = previousLineBuffer[i];
place &= 0x0F;
if (max < place)
{
count=1;
max = place;
dataToSend = i;
}
if (max==place)
{
count++;
}
place1 = previousLineBuffer[i+1];
place1 &= 0x0F;
if (max1 < place1)
{
count1=1;
max1 = place1;
dataToSend1 = (i+1);
}
if (max1==place1)
{
count1++;
}
}
/* dataToSend should be packed now */

//UartInt_txByte(dataToSend);
//UartInt_txByte((count<<4)|(max&0x0F)); // send count and max as one byte
//UartInt_txByte(max); // send count and max as one byte
//UartInt_txByte(max1);
UartInt_txByte(dataToSend1); // this is the maximum red location
//UartInt_txByte((count1<<4)|(max1&0x0F)); // send count1 and max1 as one byte

//UartInt_txByte(0x0F); /* send line end */
/* once all the data is sent, increment out line count by 2 since
we really get 2 lines worth of pixels on each pass */
/* Update...increment only by 1, but only send 72 double-lines */
lineCount++;

/* check to see if we have retrieved all of the needed lines */
if (lineCount >= 72) /* half 144, since we send two lines at a time */
{
/* we're done, so send the dump complete?...nope, just change
states and we should be fine */
lineCount = 0;
currentState = ST_FrameMgr_idle;

/* disable the PCLK counting overflow interrupt */
TIMSK &= DISABLE_PCLK_TIMER1_OVERFLOW_BITMASK;

CamConfig_setCamReg(0x11,0x00); /* reset the frame rate to normal*/
CamConfig_sendFifoCmds();
}
else
{
/* we have more lines to acquire in this frame, so keep on truckin...*/
PUBLISH_FAST_EVENT(FEV_PROCESS_LINE_COMPLETE);
}
}
davedave
 
Posts: 15
Joined: Wed May 10, 2006 11:02 pm
Location: Canberra Australia

Quick update

Postby davedave » Sun Aug 27, 2006 11:24 pm

The new/revised code works better, still not well. Here it is from frameMgr_processLine

for (i=0; i<(NUM_PIXELS_IN_A_DUMP_LINE+5); i+=2)
{
/* *previousLineBuffer contains red and blue data
known: low nibble of odd addresses = red
theory: low nibble of odd address AND high nibble of even addressed byte in previous line buffer */

place = ((previousLineBuffer[i]>>4)+(previousLineBuffer[i+1]&= 0x0F)+(previousLineBuffer[i+2]>>4));
if (max < place)
{
count=1;
max = place;
dataToSend = i;
}
if (max==place)
{
count++;
}


place1 = ((previousLineBuffer[i+1]&= 0x0F)+(previousLineBuffer[i+2]>>4)+(previousLineBuffer[i+3]&= 0x0F));
if (max1 < place1)
{
count1=1;
max1 = place1;
dataToSend1 = (i+1);
}
if (max1==place1)
{
count1++;
}
}
/* dataToSend should be packed now */

UartInt_txByte(dataToSend);
//UartInt_txByte((count<<4)|(max&0x0F)); // send count and max as one byte
//UartInt_txByte(max); // send count and max as one byte
//UartInt_txByte(max1);
UartInt_txByte(dataToSend1);
davedave
 
Posts: 15
Joined: Wed May 10, 2006 11:02 pm
Location: Canberra Australia


Return to AVRcam Embedded System

Who is online

Users browsing this forum: No registered users and 14 guests

cron