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