⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmucam3.ic

📁 显卡与摄像机通信的另一个例子.
💻 IC
字号:
// Adapted from code by Paul Rybski
// Simplified API for Botball by Randy Sargent 7/30/2002
// Reorganized data output and raw data commands by Jim Peterson 8/06/02
// This version of the library, I've removed the calls not being used for
// immediate simplicity. Illah 1/11/2003
// How to use this library:
//
// set the window size
// setWin(x1, y1, x2, y2)
//
// init_camera: puts the camera in YUV mode, with autogain and auto wb on
//
// trackRaw(rmin, rmax, gmin, gmax, bmin, bmax) - you can use this
//            function to call "TC" on the camera with your own,
//            custom color bounds. r is really Cr; g is really Y; and
//            b is really Cb.  -1 means comm error. 0 means no blob
//            at all. positive numbers indicate there was a blob and
//            report the confidence.
//
// After calling trackRaw, look at these variables to find the result:
// track_size:  The approximate area of the object tracked
//              0 means no object found
//              Small numbers may mean that only noise is being tracked
//              -1 means camera communications error
// track_confidence: when in the 100+ range, that means we definitely
//                   have a blob. 0 means no luck at all.
// track_x:     X position of tracked object, -40 to 40
//              Negative is left, positive is right, 0 is straight ahead
// track_y:     Y position of tracked object, -71 to 71
//              Negative is low, positive is high, 0 is level with camera
// track_area:  The area of the bounding rectangle of the tracked color
//

/* 
 * This is a bare-bones cmucam driver which handles everything in raw mode
 * without ACK/NCKs.  The serial interrupt is a dedicated cmucam packet
 * parser.
 *
 * Currently, only S, N, M and C packets are supported
 *
 * Variables defined in the cmcsci2a.asm file are:
 *
 * cmu_packet  : stores what kind of packet was returned 'M' or 'C'
 * cmu_new_val : is set to 1 when a new packet is received.  set to 0 
 *               when the packet is being transferred
 * cmu_start   : pointer to the head of the storage array.  This value must
 *               be set in this file.  Currently, it is set to point at
 *               cmucam_data[]
 * 
 *
 * In order to use, first load the cmcsci2a.icb file.
 * 
 * Then, the init_camera() function defined below must be called.

 * From that point, whenever a command is sent to the camera (for example):
 *
 * send_R_command(cmdbuff,n);
 *
 * the function will wait for a second for the CMUCam to return the
 * appropriate data.  If the camera does not return the appropriate
 * data, it this function will return false.  If the function returns
 * true, then the new data will be located in the cmucam_data[] array.
 * Use the defines at the top of this file to retrieve the data from
 * the array.
 *
 * Author Paul E. Rybski <rybski@cs.umn.edu> */

#use "cmcsci2b.icb"

#define cmu_WAIT 40L
#define cCMUCAM_DATA_SIZE 17  
persistent int CAM_MINDELT = 3; //changed from 1 dm 1/9/03
persistent int CAM_DEVFACT = 1; //chnaged from 4 dm 1/9/03

/*  packet indices like data from separate packages is read to the same
locations */

// N message starts here
#define cmu_SERVO 0   
// M message starts here, N matches
#define cmu_MX 1      
#define cmu_MY 2      
// C message starts here, N and M match
#define cmu_X1 3      
#define cmu_Y1 4
#define cmu_X2 5
#define cmu_Y2 6
#define cmu_PIXELS 7
#define cmu_CONFIDENCE 8    
// last data from N, M, or C messages above
// note that we leave a one byte buffer between message types
// S message starts here returned by TW and GM starts below
#define cmu_RMEAN 10         
#define cmu_GMEAN 11
#define cmu_BMEAN 12
#define cmu_RDEV 13
#define cmu_GDEV 14
#define cmu_BDEV 15

/* 
 * This stores the data returned from the camera 
 * The type of the packet is stored in the variable 'cmu_packet'
 * The remaining values depend on the type of the first
 */
persistent char cmucam_data[cCMUCAM_DATA_SIZE];

/* This is the raw command buffer the minimum raw command is
 * 3 bytes. the format is 2 chars command id such as SW, TC or GM.
 * the next byte is the count of parameter bytes to follow. A zero
 * in cmdbuff[2] means no more bytes to command.
 * The maximum length command appears to be the CR of 16 register settings.
 *   
 */ 
persistent char cmdbuff[35]; 

/* Result data from track().
 * track_size is taken directly from cmucam_data[cmu_PIXELS]
 * track_x and track_y are taken directly from cmucam_data[cmu_MX] and 
 *   cmucam_data[cmu_MY] when supplied. If the middle mass mode is off
 *   these values are calculated as the center of the bounding box as:
 *   track_x = (cmucam_data[cmu_X1] + cmucam_data[cmu_X2])/2 and
 *   track_y = (cmucam_data[cmu_Y2] + cmucam_data[cmu_Y2])/2.
 * track_area is the area of the bounding box. That is:
 *   (x2-x1) * (y2-y1).         
 */
int track_size, track_x, track_y, track_area, track_confidence;


/* This sends an array of raw bytes of ct bytes */
void send_R_command_raw(char msg[],int ct) {
    int x=0;
    int y=0;
    // Randy added this delay 1/9/03
    // This delay is probably masking a bug somewhere in the logic
    // of this communication library
    // experimentally, 2 fails and 4 succeeds, so I'm bumping to 5
    // just to be safe
    msleep(5L);
    
    cmucam_data[16] = cmu_last_char;
    
    for (x=0;x<ct;x++)
      {
        y=msg[x];
        while (!(peek(0x102e) & 0x80) ); /* wait UART */
        poke(0x102f, y);
    }
    /* For some reason, this delay is necessary otherwise the CMUCam fails to
   * receive the command */
    msleep(cmu_WAIT);
}

/* Send a raw bytes command.  Fail if the command takes more than a 
   second to return. */
int send_R_command(char msg[],int ct) {
    long timer;
    /* Clear the flag */
    cmu_new_val = 0;
    /* Send the command */
    send_R_command_raw(msg,ct);
    /* Wait for the response */
    timer = mseconds()+1000L;
    /* If we have to wait longer than a second, drop out */
    while (timer > mseconds()) {
        /* Check the flag to see if there is a new packet */
        msleep(cmu_WAIT);
        if (1 == cmu_new_val) { 
            return 0; /* Return success */
        }
        if (2 == cmu_new_val) { 
            printf("Rcmd %c%c serial error\n",msg[0],msg[1]);
            tone(1500.,.1);
            sleep(1.0);
            return 1; /* Return success */
        }
    }
    /* Timeout occurred */
    printf("Rcmd %c%c timeout\n",msg[0],msg[1]);
    tone(1500.,.1);
    tone(1500.,.1);
    tone(1500.,.1);
    tone(1500.,.1);
    sleep(1.0);
    return 1; /* Return failure */; 
}

int init_camera()
{
    int i = 0;
    sleep(1.0); // give CMUcam a chance to boot up first!
    /* Prevents the onboard pcode to catch the incoming serial data */
    //poke(0x3c,1);
    for ( i = 0; i < cCMUCAM_DATA_SIZE; i++) cmucam_data[i] = 0;
    /* Aim the assembly-defined data pointer at the head of the array */
    cmu_start = (int)&cmucam_data[0];
    //   cmu_last_char = 58;
    cmucam_sci_init(0);
    /* Put in poll mode */
    send_R_command_raw("PM 1\r",5); 
    msleep(cmu_WAIT);
    /* Set the delay for sending the serial command from the camera */
    /* 0 - min delay and 255 - max delay.  If this is not set, the */
    /* handyboard will often freeze with receiving data from the CMUcam */
    send_R_command_raw("DM 30\r",6);
    msleep(cmu_WAIT);
    /* Put into raw mode input and output with no ACK/NCK */
    send_R_command_raw("RM 3\r",5); // do NOT send in raw (bit 3 be off!) illah
    msleep(cmu_WAIT);
    send_R_command_raw("MM 1\r",5);
    msleep(cmu_WAIT);
    send_R_command_raw("NF 1\r",5);
    msleep(cmu_WAIT);
    return 1;
    /* Initialize the interrupt */
}

///////////////////////////
// randy added 7/30/2002 //
///////////////////////////
// modified by illah - most stuff removed... 1/11/2003 //

// adds theNum in ASCII to theArray starting at index
// startWith and returns to the caller the total # of 
// characters added to theArray
// this is kludged for just 3-digit or smaller numbers!
// oh, and please only pass it positive numbers!!
int addNum(int theNum, char theArray[], int startWith)
{
    int i = 0;
    int remNum; int outerDigit;
    outerDigit = (int)(theNum/100);
    remNum = theNum % 100;
    theArray[startWith] = '0' + outerDigit;
    outerDigit = (int)(remNum/10);
    remNum = remNum % 10;
    theArray[startWith+1] = '0' + outerDigit;
    theArray[startWith+2] = '0' + remNum;
    return 3;
}

// set the window to a subset of full-window //
// to set full window, just send "sw\r" to the camera.
// that would be equivalent to "sw 1 1 80 143\r"
void setWin(int x1, int y1, int x2, int y2)
{
    int i;
    cmdbuff[0] = 'S';
    cmdbuff[1] = 'W';
    cmdbuff[2] = ' ';
    i = 3 + addNum(x1, cmdbuff, 3);
    cmdbuff[i++] = ' ';
    i = i + addNum(y1, cmdbuff, i);
    cmdbuff[i++] = ' ';
    i = i + addNum(x2, cmdbuff, i);
    cmdbuff[i++] = ' ';
    i = i + addNum(y2, cmdbuff, i);
    cmdbuff[i++] = 13;
    send_R_command_raw(cmdbuff,i);
    defer();
}



// trackRaw() is used when you directly specify the rmin, rmax,...bmax values
// for a TrackColor operation.
// This function will call TC to the camera,
// get the return values and populate them into the global data structure.
// note that trackRaw returns -1 if the command fails, 0 if the command succeeds
// but nothing trackable is found and a positive number indicating the confidence
// if a confident blob is detected
// a great blob means a confidence of 80 or 100 or more.
int trackRaw(int rmin, int rmax, int gmin, int gmax, int bmin, int bmax)
{ 
    int i;
    cmdbuff[0] = 'T';
    cmdbuff[1] = 'C';
    cmdbuff[2] = ' ';
    i = 3 + addNum(rmin, cmdbuff, 3);
    cmdbuff[i++] = ' ';
    i = i + addNum(rmax, cmdbuff, i);
    cmdbuff[i++] = ' ';
    i = i + addNum(gmin, cmdbuff, i);
    cmdbuff[i++] = ' ';
    i = i + addNum(gmax, cmdbuff, i);
    cmdbuff[i++] = ' ';
    i = i + addNum(bmin, cmdbuff, i);
    cmdbuff[i++] = ' ';
    i = i + addNum(bmax, cmdbuff, i);
    cmdbuff[i++] = 13;
    
    if (send_R_command(cmdbuff,i)) {
        
        //    if (send_R_command("TC 180 240 20 150 16 18\r",24)) {
        // command send to CMUcam failed
        track_size = -1; cam_comm_error(); track_confidence = 0;
        // Illah - added init_camera here to get poll mode back on //
        init_camera();
        return -1;
    } else {
        // in this case the communication to CMUcam succeeded...
        // cmucam_data[0...7]:
        // 0,1: CG x,y
        // 2,3-4,5:  BBOX x1,y1-x2,y2
        // 6: size (pixels+4)/8
        // 7: confidence
        msleep(cmu_WAIT); // ILLAH - put this here just to see !!!!!! ILLAH //
        track_size= cmucam_data[cmu_PIXELS];
        track_area = (cmucam_data[cmu_X2]-cmucam_data[cmu_X1])*
          (cmucam_data[cmu_Y2]-cmucam_data[cmu_Y1]);
        track_confidence = cmucam_data[cmu_CONFIDENCE];        
        
        if ((track_size > 1) && (cmucam_data[cmu_CONFIDENCE] > 0)) {
            if (cmucam_data[cmu_MX] > 0) {
                track_x= cmucam_data[cmu_MX]-40;
                track_y= cmucam_data[cmu_MY]-71;
            } else {
                track_x = ((cmucam_data[cmu_X1] + cmucam_data[cmu_Y2])/2) - 40;
                track_y = ((cmucam_data[cmu_Y1] + cmucam_data[cmu_Y2])/2) - 40;
            }
        } else {
            // this is the case when confidence is zero ; nothing tracked
            track_x= track_y= 0; track_confidence = 0;
        }
    } // end else (in the case communication succeeded)
    return track_confidence;
} // end trackRaw() //

void cam_comm_error()
{
    printf("Can't talk to   camera\n");
    tone(1500.,.1);
}
int max(int x, int y)
{ if (x > y)
      return x;
    else
      return y;
}

int min(int x, int y)
{ if (x > y)
      return y;
    else
      return x;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -