Mike Spadaru / physcom
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Pixy2CCC.h Source File

Pixy2CCC.h

00001 //
00002 // begin license header
00003 //
00004 // This file is part of Pixy CMUcam5 or "Pixy" for short
00005 //
00006 // All Pixy source code is provided under the terms of the
00007 // GNU General Public License v2 (http://www.gnu.org/licenses/gpl-2.0.html).
00008 // Those wishing to use Pixy source code, software and/or
00009 // technologies under different licensing terms should contact us at
00010 // cmucam@cs.cmu.edu. Such licensing terms are available for
00011 // all portions of the Pixy codebase presented here.
00012 //
00013 // end license header
00014 //
00015 // This file is for defining the Block struct and the Pixy template class version 2.
00016 // (TPixy2).  TPixy takes a communication link as a template parameter so that
00017 // all communication modes (SPI, I2C and UART) can share the same code.
00018 //
00019 
00020 #ifndef _PIXY2CCC_H
00021 #define _PIXY2CCC_H
00022 
00023 #include <mbed.h>
00024 #include <stdint.h>
00025 #include <stdio.h>
00026 
00027 #define CCC_MAX_SIGNATURE 7
00028 
00029 #define CCC_RESPONSE_BLOCKS 0x21
00030 #define CCC_REQUEST_BLOCKS 0x20
00031 
00032 // Defines for sigmap:
00033 // You can bitwise "or" these together to make a custom sigmap.
00034 // For example if you're only interested in receiving blocks
00035 // with signatures 1 and 5, you could use a sigmap of
00036 // PIXY_SIG1 | PIXY_SIG5
00037 #define CCC_SIG1 1
00038 #define CCC_SIG2 2
00039 #define CCC_SIG3 4
00040 #define CCC_SIG4 8
00041 #define CCC_SIG5 16
00042 #define CCC_SIG6 32
00043 #define CCC_SIG7 64
00044 #define CCC_COLOR_CODES 128
00045 
00046 #define CCC_SIG_ALL 0xff // all bits or'ed together
00047 
00048 
00049 /**
00050  * @brief Structure of CCC blocks
00051  * @see Pixy2CCC::getBlocks
00052  */
00053 struct Block {
00054     // print block structure!
00055     void print(Serial* serial)
00056     {
00057         if (serial) {
00058             int i, j;
00059             char sig[6], d;
00060             bool flag;
00061             if (m_signature > CCC_MAX_SIGNATURE) // color code! (CC)
00062             {
00063                 // convert signature number to an octal string
00064                 for (i = 12, j = 0, flag = false; i >= 0; i -= 3) {
00065                     d = (m_signature >> i) & 0x07;
00066                     if (d > 0 && !flag)
00067                         flag = true;
00068                     if (flag)
00069                         sig[j++] = d + '0';
00070                 }
00071                 sig[j] = '\0';
00072                 serial->printf("CC block sig: %s (%d decimal) x: %d y: %d width: %d height: %d angle: %d index: %d age: %d\n", sig, m_signature, m_x, m_y, m_width, m_height, m_angle, m_index, m_age);
00073             } else { // regular block.  Note, angle is always zero, so no need to print
00074                 serial->printf("sig: %d x: %d y: %d width: %d height: %d index: %d age: %d\n", m_signature, m_x, m_y, m_width, m_height, m_index, m_age);
00075             }
00076         }
00077     }
00078 
00079     uint16_t m_signature;
00080     uint16_t m_x;
00081     uint16_t m_y;
00082     uint16_t m_width;
00083     uint16_t m_height;
00084     int16_t m_angle;
00085     uint8_t m_index;
00086     uint8_t m_age;
00087 };
00088 
00089 template <class LinkType>
00090 class TPixy2;
00091 
00092 template <class LinkType>
00093 class Pixy2CCC {
00094 public:
00095     Pixy2CCC(TPixy2<LinkType>* pixy)
00096     {
00097         m_pixy = pixy;
00098     }
00099 
00100     /**
00101      * Gets all detected blocks in the most recent frame.
00102      * 
00103      * @returns an error value (<0) if it fails and PIXY_RESULT_OK if it succeeds
00104      */
00105     int8_t getBlocks(bool wait = true, uint8_t sigmap = CCC_SIG_ALL, uint8_t maxBlocks = 0xff);
00106 
00107     /* The number of blocks contained in the blocks member variable. */
00108     uint8_t numBlocks;
00109     /** 
00110      * This array contains all of the block data as a result of getBlocks(). 
00111      * The blocks in this array are sorted by area, with the largest blocks appearing 
00112      * first in the blocks array.
00113      */
00114     Block* blocks;
00115 
00116 private:
00117     TPixy2<LinkType>* m_pixy;
00118 };
00119 
00120 template <class LinkType>
00121 int8_t Pixy2CCC<LinkType>::getBlocks(bool wait, uint8_t sigmap, uint8_t maxBlocks)
00122 {
00123     blocks = NULL;
00124     numBlocks = 0;
00125 
00126     while (1) {
00127         // fill in request data
00128         m_pixy->m_bufPayload[0] = sigmap;
00129         m_pixy->m_bufPayload[1] = maxBlocks;
00130         m_pixy->m_length = 2;
00131         m_pixy->m_type = CCC_REQUEST_BLOCKS;
00132 
00133         // send request
00134         m_pixy->sendPacket();
00135         if (m_pixy->recvPacket() == 0) {
00136             if (m_pixy->m_type == CCC_RESPONSE_BLOCKS) {
00137                 blocks = (Block*)m_pixy->m_buf;
00138                 numBlocks = m_pixy->m_length / sizeof(Block);
00139                 return numBlocks;
00140             }
00141             // deal with busy and program changing states from Pixy (we'll wait)
00142             else if (m_pixy->m_type == PIXY_TYPE_RESPONSE_ERROR) {
00143                 if ((int8_t)m_pixy->m_buf[0] == PIXY_RESULT_BUSY) {
00144                     if (!wait)
00145                         return PIXY_RESULT_BUSY; // new data not available yet
00146                 } else if ((int8_t)m_pixy->m_buf[0] != PIXY_RESULT_PROG_CHANGING)
00147                     return m_pixy->m_buf[0];
00148             }
00149         } else
00150             return PIXY_RESULT_ERROR; // some kind of bitstream error
00151 
00152         // If we're waiting for frame data, don't thrash Pixy with requests.
00153         // We can give up half a millisecond of latency (worst case)
00154         wait_ms(500);
00155     }
00156 }
00157 
00158 #endif
00159