-
Notifications
You must be signed in to change notification settings - Fork 0
/
lights.py
195 lines (154 loc) · 6.78 KB
/
lights.py
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# Copyright (c) 2016 Anki, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License in the file LICENSE.txt or at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
'''Helper routines for dealing with Cozmo's lights and colors.'''
# __all__ should order by constants, event classes, other classes, functions.
__all__ = ['green', 'red', 'blue', 'white', 'off',
'green_light', 'red_light', 'blue_light', 'white_light', 'off_light',
'Color', 'Light']
import copy
from logger import *
class Color:
'''A Color to be used with a Light.
Either int_color or rgb may be used to specify the actual color.
Any alpha components (from int_color) are ignored - all colors are fully opaque.
Args:
int_color (int): A 32 bit value holding the binary RGBA value (where A
is ignored and forced to be fully opaque).
rgb (tuple): A tuple holding the integer values from 0-255 for (red, green, blue)
name (str): A name to assign to this color
'''
def __init__(self, int_color=None, rgb=None, name=None):
self.name = name
self._int_color = 0
if int_color is not None:
self._int_color = int_color | 0xff
elif rgb is not None:
self._int_color = (rgb[0] << 24) | (rgb[1] << 16) | (rgb[2] << 8) | 0xff
@property
def int_color(self):
'''int: The encoded integer value of the color.'''
return self._int_color
#: :class:`Color`: Green color instance.
green = Color(name="green", int_color=0x00ff00ff)
#: :class:`Color`: Red color instance.
red = Color(name="red", int_color=0xff0000ff)
#: :class:`Color`: Blue color instance.
blue = Color(name="blue", int_color=0x0000ffff)
#: :class:`Color`: White color instance.
white = Color(name="white", int_color=0xffffffff)
#: :class:`Color`: instance representing no color (LEDs off).
off = Color(name="off")
class Light:
'''Lights are used with LightCubes and Cozmo's backpack.
Lights may either be "on" or "off", though in practice any colors may be
assigned to either state (including no color/light).
'''
def __init__(self, on_color=off, off_color=off, on_period_ms=250,
off_period_ms=0, transition_on_period_ms=0, transition_off_period_ms=0):
self._on_color = on_color
self._off_color = off_color
self._on_period_ms = on_period_ms
self._off_period_ms = off_period_ms
self._transition_on_period_ms = transition_on_period_ms
self._transition_off_period_ms = transition_off_period_ms
@property
def on_color(self):
''':class:`Color`: The Color shown when the light is on.'''
return self._on_color
@on_color.setter
def on_color(self, color):
if not isinstance(color, Color):
raise TypeError("Must specify a Color")
self._on_color = color
@property
def off_color(self):
''':class:`Color`: The Color shown when the light is off.'''
return self._off_color
@off_color.setter
def off_color(self, color):
if not isinstance(color, Color):
raise TypeError("Must specify a Color")
self._off_color = color
@property
def on_period_ms(self):
'''int: The number of milliseconds the light should be "on" for for each cycle.'''
return self._on_period_ms
@on_period_ms.setter
def on_period_ms(self, ms):
if not 0 < ms < 2**32:
raise ValueError("Invalid value")
self._on_period_ms = ms
@property
def off_period_ms(self):
'''int: The number of milliseconds the light should be "off" for for each cycle.'''
return self._off_period_ms
@off_period_ms.setter
def off_period_ms(self, ms):
if not 0 < ms < 2**32:
raise ValueError("Invalid value")
self._off_period_ms = ms
@property
def transition_on_period_ms(self):
'''int: The number of milliseconds to take to transition the light to the on color.'''
return self._transition_on_period_ms
@transition_on_period_ms.setter
def transition_on_period_ms(self, ms):
if not 0 < ms < 2**32:
raise ValueError("Invalid value")
self._transition_on_period_ms = ms
@property
def transition_off_period_ms(self):
'''int: The number of milliseconds to take to transition the light to the off color.'''
return self._transition_off_period_ms
@transition_off_period_ms.setter
def transition_off_period_ms(self, ms):
if not 0 < ms < 2**32:
raise ValueError("Invalid value")
self._transition_off_period_ms = ms
def flash(self, on_period_ms=250, off_period_ms=250, off_color=off):
'''Convenience function to make a flashing version of an existing Light instance.
Args:
on_period_ms (int): The number of milliseconds the light should be "on" for for each cycle.
off_period_ms (int): The number of milliseconds the light should be "off" for for each cycle.
off_color (:class:`Color`): The color to flash to for the off state.
Returns:
:class:`Color` instance.
'''
flasher = copy.copy(self)
flasher.on_period_ms = on_period_ms
flasher.off_period_ms = off_period_ms
flasher.off_color=off_color
return flasher
def _set_light(msg, idx, light):
# For use with clad light messages specifically.
if not isinstance(light, Light):
raise TypeError("Expected a lights.Light")
msg.onColor[idx] = light.on_color.int_color
msg.offColor[idx] = light.off_color.int_color
msg.onPeriod_ms[idx] = light.on_period_ms
msg.offPeriod_ms[idx] = light.off_period_ms
msg.transitionOnPeriod_ms[idx] = light.transition_on_period_ms
msg.transitionOffPeriod_ms[idx] = light.transition_off_period_ms
#There is a glitch so it will always flash unless on_color==off_color
#ticket is COZMO-3319
#: :class:`Light`: A steady green colored LED light.
green_light = Light(on_color=green, off_color=green)
#: :class:`Light`: A steady red colored LED light.
red_light = Light(on_color=red, off_color=red)
#: :class:`Light`: A steady blue colored LED light.
blue_light = Light(on_color=blue, off_color=blue)
#: :class:`Light`: A steady white colored LED light.
white_light = Light(on_color=white, off_color=white)
#: :class:`Light`: A steady off (non-illuminated LED light).
off_light = Light(on_color=off, off_color=off)