Skip to content

Commit fd05f08

Browse files
committed
Update rgb sensors
1 parent 03ce522 commit fd05f08

File tree

4 files changed

+122
-47
lines changed

4 files changed

+122
-47
lines changed

python/evolutek/lib/indicators/ws2812b.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,12 @@ def set_mode(self, mode=LightningMode.Loading):
5757

5858
self.mode = mode
5959

60-
self.leds.fill(Color.Black.value)
60+
self.leds.fill(Color.Black.value.to_tupple())
6161

6262
if self.mode == LightningMode.Loading:
6363
self.current_led = self.nb_leds - 1
6464
for i in range(NB_LOADING_LED):
65-
self.leds[i] = self.loading_color.value
65+
self.leds[i] = self.loading_color.value.to_tupple()
6666

6767
elif self.mode == LightningMode.Disabled or self.mode == LightningMode.Error:
6868
self.state = False
@@ -79,25 +79,25 @@ def run(self):
7979
with self.lock:
8080
if self.mode == LightningMode.Disabled:
8181
for i in range(self.nb_leds):
82-
self.leds[i] = Color.Orange.value if self.state ^ i % 2 == 0 else Color.Black.value
82+
self.leds[i] = Color.Orange.value.to_tupple() if self.state ^ i % 2 == 0 else Color.Black.value.to_tupple()
8383
self.state = not self.state
8484

8585
elif self.mode == LightningMode.Error:
86-
self.leds.fill(Color.Red.value if self.state else Color.Black.value)
86+
self.leds.fill(Color.Red.value.to_tupple() if self.state else Color.Black.value.to_tupple())
8787
self.state = not self.state
8888

8989
elif self.mode == LightningMode.Loading:
90-
self.leds[self.current_led] = Color.Black.value
91-
self.leds[(self.current_led + NB_LOADING_LED) % self.nb_leds] = self.loading_color.value
90+
self.leds[self.current_led] = Color.Black.value.to_tupple()
91+
self.leds[(self.current_led + NB_LOADING_LED) % self.nb_leds] = self.loading_color.value.to_tupple()
9292
self.current_led = (self.current_led + 1) % self.nb_leds
9393

9494
elif self.mode == LightningMode.Running:
95-
self.leds.fill(Color.Green.value)
95+
self.leds.fill(Color.Green.value.to_tupple())
9696

9797
self.leds.show()
9898

9999
sleep(refresh[self.mode])
100100

101-
self.leds.fill(Color.Black.value)
101+
self.leds.fill(Color.Black.value.to_tupple())
102102
self.leds.show()
103103
print(f"[{self.name}] Stopped")

python/evolutek/lib/sensors/rgb_sensors.py

Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,23 @@
22
import adafruit_tcs34725
33
import board
44
import busio
5-
import time
6-
75
from enum import Enum
86
from time import sleep
97

108
from evolutek.lib.component import Component, ComponentsHolder
11-
from evolutek.lib.utils.color import Color
9+
from evolutek.lib.utils.color import RGBColor, Color
1210

1311
TCA = None
14-
CALIBRATE = 10
15-
16-
# Up -> More perturbations (more false positives)
17-
# Down -> Better detection (more false negatives)
18-
SENSITIVITY = 1.25
12+
CALIBRATION_NB_VALUES = 10
13+
DELTA_FOR_COLOR = 50
1914

2015
class TCS34725(Component):
2116

22-
def __init__(self, id, channel):
23-
self.calibration = [0, 0, 0]
17+
def __init__(self, id, channel, color_to_detect=None):
18+
self.calibration = RGBColor(0, 0, 0)
2419
self.sensor = None
2520
self.channel = channel
21+
self.color_to_detect = color_to_detect
2622
super().__init__('TCS34725', id)
2723

2824
def _initialize(self):
@@ -38,32 +34,28 @@ def _initialize(self):
3834
return True
3935

4036
def calibrate(self):
41-
for i in range(CALIBRATE):
42-
rgb = self.sensor.color_rgb_bytes
43-
self.calibration[0] += rgb[0]
44-
self.calibration[1] += rgb[1]
45-
self.calibration[2] += rgb[2]
37+
calibration = []
38+
for i in range(CALIBRATION_NB_VALUES):
39+
calibration.append(RGBColor.from_tupple(self.sensor.color_rgb_bytes))
4640
sleep(0.1)
47-
self.calibration[0] /= CALIBRATE
48-
self.calibration[1] /= CALIBRATE
49-
self.calibration[2] /= CALIBRATE
50-
# print('Setup: R = %i - G = %i - B = %i' % (self.calibration[0],self.calibration[1],self.calibration[2]))
41+
self.calibration = RGBColor.mean(calibration)
42+
print(f"[{self.name}] Sensor {self.id} calibrated with {self.calibration}")
5143

5244
def read(self):
53-
if not self.is_initialized:
54-
print('[%s] %s %d not initialized' % (self.name, self.name, self.id))
55-
return None
45+
rgb = RGBColor.from_tupple(self.sensor.color_rgb_bytes)
46+
rgb -= self.calibration
47+
color = Color.get_closest_color(rgb, self.color_to_detect if self.color_to_detect is not None else Color.__members__)
5648

57-
rgb = self.sensor.color_rgb_bytes
58-
values = [rgb[0] - self.calibration[0], rgb[1] - self.calibration[1], rgb[2] - self.calibration[2]]
59-
index = values.index(max(values))
49+
if color == Color.Unknown:
50+
print(f"[{self.name}] Sensor {self.id} didn't see any color")
6051

61-
if rgb[index] < self.calibration[index] * SENSITIVITY:
62-
return Color.Unknown
52+
dist = rgb.compute_dist(color.value)
53+
if dist >= DELTA_FOR_COLOR:
54+
print(f"[{self.name}] Sensor {self.id} detect a bad color (dist={dist})")
55+
6356

64-
res = [Color.Red, Color.Green, Color.Blue][index]
65-
if res == Color.Blue: return Color.Green
66-
return res
57+
print(f"[{self.name}] Sensor {self.id} detect color with {color.value} with dist {dist}")
58+
return color
6759

6860
def __str__(self):
6961
s = "----------\n"

python/evolutek/lib/utils/color.py

Lines changed: 91 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,101 @@
11
from enum import Enum
2+
from math import sqrt
3+
4+
class RGBColor:
5+
6+
def __init__(self, r, g, b):
7+
self.r = r
8+
self.g = g
9+
self.b = b
10+
11+
@staticmethod
12+
def from_tupple(t):
13+
return RGBColor(r, g, b)
14+
15+
def to_tupple(self):
16+
return (self.r, self.g, self.b)
17+
18+
def __str__(self) -> str:
19+
return f"(R, G, B): ({self.r}, {self.g}, {self.b})"
20+
21+
def __eq__(self, color) -> bool:
22+
return (
23+
self.r == color.r and
24+
self.g == color.g and
25+
self.b == color.b
26+
)
27+
28+
def __add__(self, color):
29+
return RGBColor(
30+
self.r + color.r,
31+
self.g + color.g,
32+
self.b + color.b
33+
)
34+
35+
def __sub__(self, color):
36+
return RGBColor(
37+
self.r - color.r,
38+
self.g - color.g,
39+
self.b - color.b
40+
)
41+
42+
def __div__(self, div: int):
43+
return RGBColor(
44+
self.r / div,
45+
self.g / div,
46+
self.b / div
47+
)
48+
49+
def __mul__(self, coef: float):
50+
if coef < 0.0 or coef > 1.0:
51+
return Color.Black.value
52+
53+
return RGBColor(self.r * coef, self.g * coef, self.b * coef)
54+
55+
@staticmethod
56+
def mean(colors):
57+
result = RGBColor(0, 0, 0)
58+
for color in colors:
59+
result += color
60+
return result / len(colors)
61+
62+
def compute_dist(self, color):
63+
tmp = self.__sub__(color)
64+
return sqrt(
65+
tmp.r ** 2 + tmp.g **2 + tmp.b **2
66+
)
267

368
class Color(Enum):
4-
Black = (0, 0, 0)
5-
Blue = (0, 0, 255)
6-
Green = (0, 255, 0)
7-
Orange = (255, 50, 0)
8-
Red = (255, 0, 0)
9-
Yellow = (255, 255, 0)
10-
Purple = (115, 25, 115)
11-
Unknown = (-1, -1, -1)
69+
Black = RGBColor(0, 0, 0)
70+
Blue = RGBColor(0, 0, 255)
71+
Green = RGBColor(0, 255, 0)
72+
Orange = RGBColor(255, 50, 0)
73+
Red = RGBColor(255, 0, 0)
74+
Yellow = RGBColor(255, 255, 0)
75+
Purple = RGBColor(115, 25, 115)
76+
Unknown = RGBColor(-1, -1, -1)
1277

1378
@staticmethod
1479
def get_by_name(name):
1580
try:
1681
return Color.__members__[name.capitalize()]
1782
except:
1883
return Color.Unknown
84+
85+
@staticmethod
86+
def get_by_rgb(rgb_color):
87+
for color in Color.__members__:
88+
if rgb_color == color.value:
89+
return color
90+
return Color.Unknown
91+
92+
@staticmethod
93+
def get_closest_color(rgb_color, colors):
94+
closest = Color.Unknow
95+
min_dist = rgb_color.compute_dist(Color.Unknow.value)
96+
for color in colors:
97+
dist = rgb_color.compute_dist(color.value)
98+
if dist < min_dist:
99+
min_dist = dist
100+
closest = color
101+
return closest

python/evolutek/tests/sensors/test_rgb_sensors.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from evolutek.lib.sensors.rgb_sensors import RGBSensors
44

5-
rgb_sensors = RGBSensors([1, 2, 3, 4])
5+
rgb_sensors = RGBSensors([1])
66
print(rgb_sensors.is_initialized())
77
print(rgb_sensors)
88

0 commit comments

Comments
 (0)