-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathIRTracking.ino
128 lines (103 loc) · 2.83 KB
/
IRTracking.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// This file contains methods used to interact with the IR sensor.
#include "PVision.h"
PVision ir;
int leftBlob = -1;
int rightBlob = -1;
float rotatedX[4];
float rotatedY[4];
int blobSize[4];
bool blobGood[4];
unsigned long lastReading = 0;
#define DIST_FILTER 0.1f
float omegaFilter = DIST_FILTER;
bool initIRTracking()
{
return ir.begin();
}
void readIRTracking()
{
int i = 0;
unsigned long now = micros();
irConfidence = 0.0f;
if ((now - lastReading) < 10000)
{
return;
}
ledPower = 0;
ir.read();
lastReading = now;
// Pre compute last known roll sin/cos in preparation for rotation
float sin_roll = sinf(roll);
float cos_roll = cosf(roll);
//Process blobs
for (i = 0; i < 4; i++)
{
blobGood[i] = ir.Blob[i].Found;
if (blobGood[i])
{
// Rotate blobs based on the dcm roll angle
rotatedX[i] = (ir.Blob[i].Scaled_X * cos_roll) + (ir.Blob[i].Scaled_Y * sin_roll);
rotatedY[i] = (ir.Blob[i].Scaled_X * -sin_roll) + (ir.Blob[i].Scaled_Y * cos_roll);
blobSize[i] = ir.Blob[i].Size;
}
}
// Test the Left blob
if (leftBlob < 0 || !blobGood[leftBlob])
{
//Left blob missing
leftBlob = -1;
for (i = 0; i < 4; i++)
{
if (i != rightBlob && blobGood[i])
{
leftBlob = i;
break;
}
}
}
// Test the Right blob
if (rightBlob < 0 || !blobGood[rightBlob])
{
//Right blob missing
rightBlob = -1;
for (i = 0; i < 4; i++)
{
if (i != leftBlob && blobGood[i])
{
rightBlob = i;
break;
}
}
}
// Check if we can compute orientation
if (leftBlob >= 0 && rightBlob >= 0)
{
// We have 2 blobs. Swap them if needed
if (rotatedX[leftBlob] > rotatedX[rightBlob])
{
// swap
int tmp = leftBlob;
leftBlob = rightBlob;
rightBlob = tmp;
}
// Both blobs, compute distance
float deltaX = abs(rotatedX[leftBlob] - rotatedX[rightBlob]);
float deltaY = abs(rotatedY[leftBlob] - rotatedY[rightBlob]);
// Check if they are at the right distance
if (deltaX > 0.075f && deltaX < 0.500f && deltaY < 0.075f)
{
irHeading = (rotatedX[leftBlob] + rotatedX[rightBlob]) * 0.5f;
irPitch = (rotatedY[leftBlob] + rotatedY[rightBlob]) * 0.5f;
irConfidence = constrain(1.0f - max(abs(irHeading * 4.5f), abs(irPitch * 3.8f)), 0.0f , 1.0f);
omegaFilter = irConfidence * DIST_FILTER;
// Note that since the two blobs are likely level, no need to account for DeltaY - we save a fer usec
omegaBlobs = (omegaBlobs * (1.0f - omegaFilter)) + (deltaX * omegaFilter);
}
else
{
// both blobs to their rooms for the evening
leftBlob = -1;
rightBlob = -1;
}
}
}