cette librairie contient les fonctions de base permettant de detecter un objet avec la camera pixy
Revision 0:a1e10abfbd19, committed 2020-11-18
- Comitter:
- michelmoulin
- Date:
- Wed Nov 18 13:12:20 2020 +0000
- Commit message:
- cette version de programme permet d'afficher les coordonnees x et y d'un objet detecte par la camera pixy.
Changed in this revision
diff -r 000000000000 -r a1e10abfbd19 Pixy.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Pixy.h Wed Nov 18 13:12:20 2020 +0000 @@ -0,0 +1,14 @@ +#ifndef _PIXY_H +#define _PIXY_H + +#include "TPixy.h" +#include "TPixyInterface.h" + +class PixySPI : public TPixy<PixyInterfaceSPI> +{ +public: + PixySPI(SPI* spi, Serial* serialOut = NULL, uint16_t arg = PIXY_DEFAULT_ARGVAL) : + TPixy<PixyInterfaceSPI>((new PixyInterfaceSPI(spi)), serialOut, arg) {} +}; + +#endif \ No newline at end of file
diff -r 000000000000 -r a1e10abfbd19 TPixy.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TPixy.h Wed Nov 18 13:12:20 2020 +0000 @@ -0,0 +1,212 @@ +// +// begin license header +// +// This file is part of Pixy CMUcam5 or "Pixy" for short +// +// All Pixy source code is provided under the terms of the +// GNU General Public License v2 (http://www.gnu.org/licenses/gpl-2.0.html). +// Those wishing to use Pixy source code, software and/or +// technologies under different licensing terms should contact us at +// cmucam@cs.cmu.edu. Such licensing terms are available for +// all portions of the Pixy codebase presented here. +// +// end license header +// +// This file is for defining the Block struct and the Pixy template class. +// (TPixy). TPixy takes a communication link as a template parameter so that +// all communication modes (SPI, I2C and UART) can share the same code. +// + +#ifndef _TPIXY_H +#define _TPIXY_H + +#include "mbed.h" +#include "TPixyInterface.h" + +// Communication/misc parameters +#define PIXY_INITIAL_ARRAYSIZE 30 +#define PIXY_MAXIMUM_ARRAYSIZE 130 +#define PIXY_START_WORD 0xaa55 +#define PIXY_START_WORD_CC 0xaa56 +#define PIXY_START_WORDX 0x55aa +#define PIXY_MAX_SIGNATURE 7 +#define PIXY_DEFAULT_ARGVAL 0xffff + +// Pixy x-y position values +#define PIXY_MIN_X 0L +#define PIXY_MAX_X 319L +#define PIXY_MIN_Y 0L +#define PIXY_MAX_Y 199L + +// RC-servo values +#define PIXY_RCS_MIN_POS 0L +#define PIXY_RCS_MAX_POS 1000L +#define PIXY_RCS_CENTER_POS ((PIXY_RCS_MAX_POS-PIXY_RCS_MIN_POS)/2) + +enum BlockType { + NORMAL_BLOCK, + CC_BLOCK +}; + +struct Block { + // print block structure! + uint16_t signature; + uint16_t x; + uint16_t y; + uint16_t width; + uint16_t height; + uint16_t angle; +}; + +template <class TPixyInterface> class TPixy +{ +public: + Serial* serial; + Block *blocks; + + TPixy(TPixyInterface* type, Serial* serialOut = NULL, uint16_t arg = PIXY_DEFAULT_ARGVAL); + ~TPixy(); + + uint16_t getBlocks(uint16_t maxBlocks = 1000); + int8_t setBrightness(uint8_t brightness); + int8_t setLED(uint8_t r, uint8_t g, uint8_t b); + +private: + TPixyInterface* link; + BlockType blockType; + bool getStart(); + void resize(); + bool skipStart; + uint16_t blockCount; + uint16_t blockArraySize; +}; + +template <class TPixyInterface> TPixy<TPixyInterface>::TPixy(TPixyInterface* type, Serial* serialOut, uint16_t arg) : serial(serialOut), link(type) +{ + skipStart = false; + blockCount = 0; + blockArraySize = PIXY_INITIAL_ARRAYSIZE; + blocks = (Block *)malloc(sizeof(Block)*blockArraySize); + link->setArg(arg); +} + +template <class TPixyInterface> TPixy<TPixyInterface>::~TPixy() +{ + free(blocks); +} + +template <class TPixyInterface> bool TPixy<TPixyInterface>::getStart() +{ + uint16_t w, lastw; + lastw = 0xffff; + while(true) { + w = link->getWord(); + if (w == 0 && lastw == 0) { + wait_ms(10); + return false; + } else if (w == PIXY_START_WORD && lastw == PIXY_START_WORD) { + blockType = NORMAL_BLOCK; + return true; + } else if (w == PIXY_START_WORD_CC && lastw == PIXY_START_WORD) { + blockType = CC_BLOCK; + return true; + } else if (w==PIXY_START_WORDX) { + if (serial != NULL) { + serial->printf("reorder"); + } + link->getByte(); // resync + } + lastw = w; + } +} + +template <class TPixyInterface> void TPixy<TPixyInterface>::resize() +{ + blockArraySize += PIXY_INITIAL_ARRAYSIZE; + blocks = (Block *)realloc(blocks, sizeof(Block)*blockArraySize); +} + +template <class TPixyInterface> uint16_t TPixy<TPixyInterface>::getBlocks(uint16_t maxBlocks) +{ + uint8_t i; + uint16_t w, checksum, sum; + Block *block; + + if (!skipStart) { + if (getStart() == false) { + return 0; + } + } else { + skipStart = false; + } + for(blockCount = 0; blockCount < maxBlocks && blockCount < PIXY_MAXIMUM_ARRAYSIZE;) { + checksum = link->getWord(); + if (checksum == PIXY_START_WORD) { // we've reached the beginning of the next frame + skipStart = true; + blockType = NORMAL_BLOCK; + if (serial != NULL) { + serial->printf("skip"); + } + return blockCount; + } else if (checksum == PIXY_START_WORD_CC) { + skipStart = true; + blockType = CC_BLOCK; + return blockCount; + } else if (checksum == 0) { + return blockCount; + } + if (blockCount > blockArraySize) { + resize(); + } + block = blocks + blockCount; + + for (i = 0, sum = 0; i < sizeof(Block)/sizeof(uint16_t); i++) { + if (blockType == NORMAL_BLOCK && i >= 5) { // skip + block->angle = 0; + break; + } + w = link->getWord(); + sum += w; + *((uint16_t *)block + i) = w; + } + + if (checksum == sum) { + blockCount++; + } else { + w = link->getWord(); + if (serial != NULL) { + serial->printf("cs error"); + } + } + if (w == PIXY_START_WORD) { + blockType = NORMAL_BLOCK; + } else if (w == PIXY_START_WORD_CC) { + blockType = CC_BLOCK; + } else { + return blockCount; + } + } + return blockCount; +} + +template <class TPixyInterface> int8_t TPixy<TPixyInterface>::setBrightness(uint8_t brightness) +{ + uint8_t outBuf[3]; + outBuf[0] = 0x00; + outBuf[1] = 0xfe; + outBuf[2] = brightness; + return link->send(outBuf, 3); +} + +template <class TPixyInterface> int8_t TPixy<TPixyInterface>::setLED(uint8_t r, uint8_t g, uint8_t b) +{ + uint8_t outBuf[5]; + outBuf[0] = 0x00; + outBuf[1] = 0xfd; + outBuf[2] = r; + outBuf[3] = g; + outBuf[4] = b; + return link->send(outBuf, 5); +} + +#endif \ No newline at end of file
diff -r 000000000000 -r a1e10abfbd19 TPixyInterface.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TPixyInterface.cpp Wed Nov 18 13:12:20 2020 +0000 @@ -0,0 +1,108 @@ +#include "TPixyInterface.h" + +PixyInterfaceSPI::PixyInterfaceSPI(SPI* interface) : TPixyInterface(), spi(interface) {} + +uint16_t PixyInterfaceSPI::getWord() +{ + // ordering is different (big endian) because Pixy is sending 16 bits through SPI + // instead of 2 bytes in a 16-bit word as with I2C + uint16_t w; + if (inQ.read(&w)) { + return w; + } + return getWordHw(); +} + +uint8_t PixyInterfaceSPI::getByte() +{ + //return SPI.transfer(0x00); + return spi->write(0x00); +} + +int8_t PixyInterfaceSPI::send(uint8_t *data, uint8_t len) +{ + int i; + // check to see if we have enough space in our circular queue + if (outQ.freeLen() < len) { + return -1; + } + for (i = 0; i < len; i++) { + outQ.write(data[i]); + } + flushSend(); + return len; +} + +void PixyInterfaceSPI::setArg(uint16_t arg) {} + +uint16_t PixyInterfaceSPI::getWordHw() +{ + // ordering is different (big endian) because Pixy is sending 16 bits through SPI + // instead of 2 bytes in a 16-bit word as with I2C + uint16_t w; + uint8_t c, c_out = 0; + + if (outQ.read(&c_out)) { + w = spi->write(PIXY_SYNC_BYTE_DATA); + //w = SPI.transfer(PIXY_SYNC_BYTE_DATA); + } else { + w = spi->write(PIXY_SYNC_BYTE); + //w = SPI.transfer(PIXY_SYNC_BYTE); + } + w <<= 8; + c = spi->write(c_out); + //c = SPI.transfer(cout); + w |= c; + return w; +} + +void PixyInterfaceSPI::flushSend() +{ + uint16_t w; + while(outQ.len) { + w = getWordHw(); + inQ.write(w); + } +} + + + + +template <class BufType> CircularQ<BufType>::CircularQ() +{ + len = 0; + writeIndex = 0; + readIndex = 0; +} + +template <class BufType> bool CircularQ<BufType>::read(BufType *c) +{ + if (len) { + *c = buf[readIndex++]; + len--; + if (readIndex == PIXY_BUF_SIZE) { + readIndex = 0; + } + return true; + } else { + return false; + } +} + +template <class BufType> uint8_t CircularQ<BufType>::freeLen() +{ + return PIXY_BUF_SIZE - len; +} + +template <class BufType> bool CircularQ<BufType>::write(BufType c) +{ + if (freeLen() == 0) { + return false; + } + buf[writeIndex++] = c; + len++; + if (writeIndex == PIXY_BUF_SIZE) { + writeIndex = 0; + } + return true; +} \ No newline at end of file
diff -r 000000000000 -r a1e10abfbd19 TPixyInterface.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TPixyInterface.h Wed Nov 18 13:12:20 2020 +0000 @@ -0,0 +1,76 @@ +// +// begin license header +// +// This file is part of Pixy CMUcam5 or "Pixy" for short +// +// All Pixy source code is provided under the terms of the +// GNU General Public License v2 (http://www.gnu.org/licenses/gpl-2.0.html). +// Those wishing to use Pixy source code, software and/or +// technologies under different licensing terms should contact us at +// cmucam@cs.cmu.edu. Such licensing terms are available for +// all portions of the Pixy codebase presented here. +// +// end license header +// +// This file is for defining the SPI-related classes. It's called Pixy.h instead +// of Pixy_SPI.h because it's the default/recommended communication method +// with Arduino. This class assumes you are using the ICSP connector to talk to +// Pixy from your Arduino. For more information go to: +// +//http://cmucam.org/projects/cmucam5/wiki/Hooking_up_Pixy_to_a_Microcontroller_(like_an_Arduino) +// + +#ifndef _TPIXY_INTERFACE_H +#define _TPIXY_INTERFACE_H + +#include "TPixy.h" + +#define PIXY_SYNC_BYTE 0x5a +#define PIXY_SYNC_BYTE_DATA 0x5b +#define PIXY_BUF_SIZE 16 + +class TPixyInterface +{ +public: + TPixyInterface() {} + virtual int8_t send(uint8_t *data, uint8_t len) = 0; + virtual void setArg(uint16_t arg) = 0; + virtual uint16_t getWord() = 0; + virtual uint8_t getByte() = 0; +}; + + +template <class BufType> class CircularQ +{ +public: + BufType buf[PIXY_BUF_SIZE]; + uint8_t len; + uint8_t writeIndex; + uint8_t readIndex; + + CircularQ(); + bool read(BufType *c); + uint8_t freeLen(); + bool write(BufType c); +}; + +class PixyInterfaceSPI : TPixyInterface +{ +public: + SPI* spi; + PixyInterfaceSPI(SPI* interface); + virtual uint16_t getWord(); + virtual uint8_t getByte(); + virtual int8_t send(uint8_t *data, uint8_t len); + virtual void setArg(uint16_t arg); + +private: + // we need a little circular queues for both directions + CircularQ<uint8_t> outQ; + CircularQ<uint16_t> inQ; + + uint16_t getWordHw(); + void flushSend(); +}; + +#endif