00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef __NXTCAM_H__
00013 #define __NXTCAM_H__
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #pragma systemFile
00043
00044 #ifndef __COMMON_H__
00045 #include "common.h"
00046 #endif
00047
00048 #define MAX_BLOBS 8
00049 #define NXTCAM_I2C_ADDR 0x02
00050 #define NXTCAM_CMD_REG 0x41
00051 #define NXTCAM_COUNT_REG 0x42
00052 #define NXTCAM_DATA_REG 0x43
00053
00054 #define SIDE_CENTER(X1, X2) ((X1 + X2) / 2)
00055
00056
00057 typedef struct {
00058 int x1;
00059 int y1;
00060 int x2;
00061 int y2;
00062 int colour;
00063 int size;
00064 } blob;
00065
00066
00067 typedef blob blob_array[MAX_BLOBS];
00068
00069 tByteArray NXTCAM_I2CRequest;
00070 tByteArray NXTCAM_I2CReply;
00071
00072
00073 bool NXTCAMinit(tSensors link, ubyte address = NXTCAM_I2C_ADDR);
00074 bool NXTCAMinitTL(tSensors link, ubyte address = NXTCAM_I2C_ADDR);
00075 int NXTCAMgetBlobs(tSensors link, blob_array &blobs, bool mergeBlobs, ubyte address = NXTCAM_I2C_ADDR);
00076 int NXTCAMgetBlobs(tSensors link, blob_array &blobs, ubyte address = NXTCAM_I2C_ADDR);
00077
00078
00079 bool _camera_cmd(tSensors link, byte cmd, ubyte address);
00080 int _mergeBlobs(int blob1, int blob2, int nblobs, blob_array &blobs);
00081 int _merge(int nblobs, blob_array &blobs);
00082 void _sortBlobs(int nblobs, blob_array &blobs);
00083 void NXTCAMgetAverageCenter(blob_array &blobs, int nblobs, int colourindex, int &x, int &y);
00084 void NXTCAMgetCenter(blob_array &blobs, int index, int &x, int &y);
00085
00086
00087 bool still_merging = false;
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 bool _camera_cmd(tSensors link, byte cmd, ubyte address) {
00099 NXTCAM_I2CRequest[0] = 3;
00100 NXTCAM_I2CRequest[1] = address;
00101 NXTCAM_I2CRequest[2] = NXTCAM_CMD_REG;
00102 NXTCAM_I2CRequest[3] = cmd;
00103
00104 return writeI2C(link, NXTCAM_I2CRequest);
00105 }
00106
00107
00108
00109
00110
00111
00112
00113 bool NXTCAMinit(tSensors link, ubyte address) {
00114 if (!_camera_cmd(link, 'D', address))
00115 return false;
00116 wait1Msec(500);
00117
00118 if (!_camera_cmd(link, 'A', address))
00119 return false;
00120 wait1Msec(500);
00121
00122 if (!_camera_cmd(link,'B', address))
00123 return false;
00124 wait1Msec(500);
00125
00126 if (!_camera_cmd(link,'E', address))
00127 return false;
00128 wait1Msec(500);
00129
00130 return true;
00131 }
00132
00133
00134
00135
00136
00137
00138
00139
00140 bool NXTCAMinitTL(tSensors link, ubyte address) {
00141 if (!_camera_cmd(link, 'D', address))
00142 return false;
00143 wait1Msec(500);
00144
00145 if (!_camera_cmd(link, 'X', address))
00146 return false;
00147 wait1Msec(500);
00148
00149 if (!_camera_cmd(link,'L', address))
00150 return false;
00151 wait1Msec(500);
00152
00153 if (!_camera_cmd(link,'E', address))
00154 return false;
00155
00156 wait1Msec(500);
00157 return true;
00158 }
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169 int NXTCAMgetBlobs(tSensors link, blob_array &blobs, bool mergeBlobs, ubyte address) {
00170 int _nblobs = NXTCAMgetBlobs(link, blobs, address);
00171 if (mergeBlobs == true)
00172 return _merge(_nblobs, blobs);
00173 return _nblobs;
00174 }
00175
00176
00177
00178
00179
00180
00181
00182
00183 int NXTCAMgetBlobs(tSensors link, blob_array &blobs, ubyte address) {
00184 int _nblobs = 0;
00185
00186
00187 memset(blobs, 0, sizeof(blob_array));
00188
00189
00190 NXTCAM_I2CRequest[0] = 2;
00191 NXTCAM_I2CRequest[1] = address;
00192 NXTCAM_I2CRequest[2] = NXTCAM_COUNT_REG;
00193
00194 if (!writeI2C(link, NXTCAM_I2CRequest, NXTCAM_I2CReply, 1))
00195 return -1;
00196
00197 _nblobs = NXTCAM_I2CReply[0];
00198 if (_nblobs > MAX_BLOBS) {
00199 return -1;
00200 }
00201
00202
00203 for (int _i = 0; _i < _nblobs; _i++) {
00204
00205
00206 NXTCAM_I2CRequest[0] = 2;
00207 NXTCAM_I2CRequest[1] = address;
00208 NXTCAM_I2CRequest[2] = NXTCAM_DATA_REG + _i * 5;
00209
00210 if (!writeI2C(link, NXTCAM_I2CRequest, NXTCAM_I2CReply, 5))
00211 return -1;
00212
00213
00214 blobs[_i].colour = (int)NXTCAM_I2CReply[0];
00215 blobs[_i].x1 = (int)NXTCAM_I2CReply[1];
00216 blobs[_i].y1 = (int)NXTCAM_I2CReply[2];
00217 blobs[_i].x2 = (int)NXTCAM_I2CReply[3];
00218 blobs[_i].y2 = (int)NXTCAM_I2CReply[4];
00219 blobs[_i].size = abs(blobs[_i].x2 - blobs[_i].x1) * abs(blobs[_i].y2 - blobs[_i].y1);
00220 }
00221 return _nblobs;
00222 }
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 int _merge(int nblobs, blob_array &blobs) {
00233 still_merging = true;
00234 while (still_merging == true) {
00235 still_merging = false;
00236 for(int i = 0; i < nblobs; i++) {
00237 for(int j = i+1; j < nblobs; j++) {
00238 nblobs = _mergeBlobs(i,j, nblobs, blobs);
00239 }
00240 }
00241 }
00242 return nblobs;
00243 }
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256 int _mergeBlobs(int blob1, int blob2, int nblobs, blob_array &blobs) {
00257 int _blob1_center;
00258 int _blob2_center;
00259 int _blob1_proj;
00260 int _blob2_proj;
00261 bool _overlapx = false;
00262 bool _overlapy = false;
00263
00264
00265 if (blobs[blob1].size == 0 || blobs[blob2].size == 0)
00266 return nblobs;
00267
00268
00269 if (blobs[blob1].colour != blobs[blob2].colour)
00270 return nblobs;
00271
00272
00273
00274 _blob1_center = SIDE_CENTER(blobs[blob1].x1, blobs[blob1].x2);
00275 _blob2_center = SIDE_CENTER(blobs[blob2].x1, blobs[blob2].x2);
00276 _blob1_proj = blobs[blob1].x2 - _blob1_center;
00277 _blob2_proj = blobs[blob2].x2 - _blob2_center;
00278
00279
00280 if ((_blob1_proj + _blob2_proj) > abs(_blob1_center - _blob2_center))
00281 _overlapx = true;
00282
00283
00284
00285 _blob1_center = SIDE_CENTER(blobs[blob1].y1, blobs[blob1].y2);
00286 _blob2_center = SIDE_CENTER(blobs[blob2].y1, blobs[blob2].y2);
00287 _blob1_proj = blobs[blob1].y2 - _blob1_center;
00288 _blob2_proj = blobs[blob2].y2 - _blob2_center;
00289
00290
00291 if ((_blob1_proj + _blob2_proj) > abs(_blob1_center - _blob2_center))
00292 _overlapy = true;
00293
00294
00295
00296
00297
00298 if ((_overlapx == true) && (_overlapy == true)) {
00299 blobs[blob1].x1 = min2(blobs[blob1].x1, blobs[blob2].x1);
00300 blobs[blob1].y1 = min2(blobs[blob1].y1, blobs[blob2].y1);
00301 blobs[blob1].x2 = max2(blobs[blob1].x2, blobs[blob2].x2);
00302 blobs[blob1].y2 = max2(blobs[blob1].y2, blobs[blob2].y2);
00303 blobs[blob1].size = abs(blobs[blob1].x2 - blobs[blob1].x1) * abs(blobs[blob1].y2 - blobs[blob1].y1);
00304
00305 for (int _i = blob2; _i < nblobs - 1; _i++) {
00306 memcpy(blobs[_i], blobs[_i+1], sizeof(blob));
00307 }
00308
00309 nblobs--;
00310 memset(blobs[nblobs], 0, sizeof(blob));
00311 still_merging = true;
00312 }
00313 _sortBlobs(nblobs, blobs);
00314
00315
00316 return nblobs;
00317 }
00318
00319
00320
00321
00322
00323
00324
00325
00326 void _sortBlobs(int nblobs, blob_array &blobs) {
00327 blob _tmpBlob;
00328 int i, j;
00329
00330
00331 for (i = 1; i < nblobs; i++) {
00332 if (blobs[i-1].size >= blobs[i].size )
00333 continue;
00334
00335 memcpy(_tmpBlob, blobs[i], sizeof(blob));
00336
00337
00338 for (j = i-1; j >= 0; j--) {
00339 if ( blobs[j].size >= _tmpBlob.size )
00340 break;
00341 memcpy(blobs[j+1], blobs[j], sizeof(blob));
00342 }
00343
00344 memcpy(blobs[j+1], _tmpBlob, sizeof(blob));
00345 }
00346 }
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 void NXTCAMgetAverageCenter(blob_array &blobs, int nblobs, int colourindex, int &x, int &y) {
00359 long _totalX = 0;
00360 long _totalY = 0;
00361 int _counter = 0;
00362
00363 for (int i = 0; i < nblobs; i++){
00364 if ((blobs[i].colour == colourindex) && (blobs[i].size > 400)) {
00365 _totalX += SIDE_CENTER(blobs[i].x1, blobs[i].x2);
00366 _totalY += SIDE_CENTER(blobs[i].y1, blobs[i].y2);
00367 _counter++;
00368 }
00369 }
00370 x = _totalX / (_counter - 1);
00371 y = _totalY / (_counter -1);
00372 }
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384 void NXTCAMgetCenter(blob_array &blobs, int index, int &x, int &y) {
00385 x = SIDE_CENTER(blobs[index].x1, blobs[index].x2);
00386 y = SIDE_CENTER(blobs[index].y1, blobs[index].y2);
00387 }
00388
00389 #endif // __NXTCAM_H__
00390
00391
00392
00393
00394
00395